Thursday, July 25, 2013

Another Dart Pub Deploy Attempt

One of the truly nice things about blogging every day is that often I find my next topic suggested and even outlined by folks that are crazy enough to be reading along. One such individual, Robert, suggested in the comments of last night's post that I try a different approach with Dart pub deploy command.

As and aside, comments and suggestions are especially welcome and appreciated when I have spent too much of the day enjoying a conference and do not have the proper amount of time to plan (or think) about a post. And yes, contrary to public perception, I do put some actual thought into these things beforehand. I wonder why I am rambling...

Anyhow, the goal remains the same: to see if I can get the pub deploy command to deploy my code from this state:
➜  ice-beta git:(gh-pages) ✗ tree . -P 'index*|*.dart' -l -L 2
├── index.html
├── main.dart
└── packages
    ├── browser -> /home/chris/.pub-cache/hosted/
    ├── crypto -> /home/chris/.pub-cache/hosted/
    ├── ice_code_editor -> /home/chris/.pub-cache/hosted/
    ├── js -> /home/chris/.pub-cache/hosted/
    ├── meta -> /home/chris/.pub-cache/hosted/
    └── unittest -> /home/chris/.pub-cache/hosted/

7 directories, 2 files
Into something that will work on GitHub pages. The primary obstacle to this is the symbolic links that Dart Pub normally uses. The other obstacle being that the pub deploy command seems to expect code to be in a web sub-directory.

Robert's suggestion was to place a main entry point in the web sub-directory that imports the real (i.e. the current) main.dart entry point. The hope being that this would let the code remain as-is, but still allow pub deploy to to the necessary compilation to JavaScript and removal of the packages symbolic links.

So I create web/main.dart as:
import '../main.dart' as Main;

main()=> Main.main();
Then try a pub deploy:
➜  ice-beta git:(gh-pages) ✗ pub deploy
Finding entrypoints...
Copying   web/          → deploy/
Compiling web/main.dart → deploy/main.dart.js
web/main.dart:1:8: Error: no library name found in file:///home/chris/repos/gamingjs/ice-beta/main.dart
import '../main.dart' as Main;
Failed to compile "/home/chris/repos/gamingjs/ice-beta/web/main.dart".
So I add a library statement to the “real” main script:
library main;

import 'package:ice_code_editor/ice.dart' as ICE;

main()=> new ICE.Full();
With that pub deploy works:
➜  ice-beta git:(gh-pages) ✗ pub deploy
Finding entrypoints...
Copying   web/          → deploy/
Compiling web/main.dart → deploy/main.dart.js
But the layout still does not seem as though it is going to work. The index.html in my sub-directory points to the main.dart file in my sub-directory. For Dart-enabled browsers that will work just fine, except that the symbolic links will still not resolve once published to GitHub pages:
➜  ice-beta git:(gh-pages) ✗ tree . -P 'main.dart.js|index*|*.dart' -l -L 2
├── deploy
│   ├── main.dart
│   └── main.dart.js
├── index.html
├── main.dart
├── packages
│   ├── browser -> /home/chris/.pub-cache/hosted/
│   ├── crypto -> /home/chris/.pub-cache/hosted/
│   ├── ice_code_editor -> /home/chris/.pub-cache/hosted/
│   ├── js -> /home/chris/.pub-cache/hosted/
│   ├── meta -> /home/chris/.pub-cache/hosted/
│   └── unittest -> /home/chris/.pub-cache/hosted/
└── web
    ├── main.dart
    └── packages -> ../packages  [recursive, not followed]

10 directories, 5 files
Further, the index.html and main.dart in my web application directory will not work with non-Dart browsers since there is no main.dart.js file in there for legacy browser to fallback to.

I might be able to post-process this with another script—moving the deploy/main.dart.js into the application directory. But I already have a script that solves my current use-case. So unless I am missing something (which is certainly possible in my current state—any ideas Robert?) it's back to OSCON partying. Woo hoo!

UPDATE: Per a suggestion from Paul Evans, I tried setting the HOME shell variable to the current working directory:
➜  ice-beta git:(gh-pages) ✗ HOME=`pwd` pub install
Resolving dependencies.....................
Downloading js 0.0.24 from hosted...
Downloading ice_code_editor 0.0.9 from hosted...
Downloading browser 0.6.5 from hosted...
Downloading meta 0.6.5 from hosted...
Downloading crypto 0.6.5 from hosted...
Downloading unittest 0.6.5 from hosted...
Dependencies installed!
(using HOME=. creates packages symlinks that do not resolve)

That looks promising in that all of my dependencies, which would otherwise be re-used from the system cache, are downloaded again. However, I am still left with a symbolic links to a package cache—only the package cache is now in the current directory:
➜  ice-beta git:(gh-pages) ✗ ls -l packages
total 4
lrwxrwxrwx 1 chris chris 54 Jul 26 11:16 browser -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
lrwxrwxrwx 1 chris chris 53 Jul 26 11:17 crypto -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
lrwxrwxrwx 1 chris chris 62 Jul 26 11:16 ice_code_editor -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
lrwxrwxrwx 1 chris chris 50 Jul 26 11:17 js -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
lrwxrwxrwx 1 chris chris 51 Jul 26 11:16 meta -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
lrwxrwxrwx 1 chris chris 55 Jul 26 11:16 unittest -> /home/chris/repos/gamingjs/ice-beta/.pub-cache/hosted/
That is not really an improvement. The /home/chris directory does not exist on GitHub. Even if it did, the symbolic links will not work in GitHub pages. Even if they did, “dot” files and directories like .pub-cache will not work with GitHub pages.

Really, this does not matter too much as publishing a Dart application to GitHub pages is something of a rarity (I would think) and I have a 14 line Bash script that takes care of it for me.

Day #823


  1. Yeah :/
    Thanks for the mention in your write up!
    I was using the technique to pull from git as one user and run a dart service process as another user without giving access to the pulling user's home directory.

    1. Ah, makes sense. Like I said in the post, it's not a big deal that it doesn't work for me. I have a 10 line Bash script that does the job. It would be cool if dart pub “just worked” for my GitHub pages use-case, but I can muddle through as-is.

      Either way, thanks for the suggestion. I hadn't thought of that and, even though it didn't work in this case, it will come in handy elsewhere.