Wanted: Hacker to port Pop, Pop, Win! to StageXL

tl;dr: Want an interesting Dart project? Port Pop, Pop, Win! to StageXL. If you do a good job, you're code will get into the Dart SDK.

When I wrote Pop, Pop, Win! I hacked together an HTML Canvas graphics library into bot_web. The library – bot_retained – did everything I needed, but I really haven't done much with it in over a year.

In the mean time, StageXL has been going nuts. It supports rendering to Canvas and WebGL. It supports Texture Packer. Bernhard has been keeping it fresh.

I'm actively trying to cleanup a bunch of little projects I've built over the last couple of years. Deprecating my own retained graphics library and moving folks towards StageXL seems like goodness.

Interested in doing the port?

The source code for PPW now lives in the Dart SDK. I'd suggest doing a copy-paste of the project into a new Git repository and starting there. The graphics bits are pretty well isolated. If you're pretty serious and can show that you've made a stab, I'm happy to offer help.

Dig in. Send me a link to your project on GitHub if you make progress or hit any bumps.

Happy hacking!


Tracking changes to PART of the Dart SDK

For historical reasons, the Dart project uses Subversion for source control.

There are a few folks who would like to use Git for the project, including me, but it's not the top of our priority list.

You can get some of the benefits of Git by looking at or even cloning our GitHub mirror.

One of my favorite uses: tracking changes to an individual package.


1 - Navigate to a package of interest, say unittest.

2 - Click on the History link.

3 - Notice that kevmoo has been making a lot of changes lately.

This is a great way to see what changes have happened since the latest release of a package or just to track individual parts of the Dart project.

Nice, huh?


Dart Package Devs: Put version constraints in your pubspec


  • Update: this guidance is specific Dart packages. I'll write about Dart apps soon.
  • Read about the Pub Versioning Philosophy.
  • If your package uses new features in the SDK or packages, make sure you set an inclusive minimum version constraint – >= X.Y.Z – to avoid breaking folks who have not yet upgraded.
  • Set exclusive maximum version constraints – <X.Y.Z – to make sure major releases of the SDK and packages don't break your code.
  • Understand how pre-v1.0 are versioned with regard to breaking changes.
  • Take a look at pubspec files in our SDK to understand how we handle versioning. Example: http package pubspec.yaml.

New features and minimum version constraints

Dart v1.3 is coming soon. String has learned a few tricks since v1.2, specifically:
  • String padLeft(int newLength, String padding)
  • String padLeft(int newLength, String padding)
  • String trimLeft()
  • String trimRight()
Awesome, right? I can imagine package authors doing the following:
  1. Download Dart 1.3 Editor and SDK
  2. Replace all internal hacks with new String functions.
  3. Release?
No! #3 should be: Update your pubspec.yaml.

pubspec.yaml content

In the Dart Editor

Setting the minimum SDK to 1.3.0 tells the pub tools and your users the users that a package requires at least v1.3 of the Dart SDK. Better to get an error from pub install or pub update than to get static warnings or runtime errors about missing functions.

You'll also notice more than just an inclusive minimum SDK constraint – >=1.3.0 – there's also an exclusive maximum SDK constraint – <2.0.0.

Our promise it to follow semantic versioning for the SDK and our shipped packages. The short version:
  • For a version X.Y.Z
  • Increases to Y indicate new features, but no breaking changes.
  • Increases to X indicate breaking changes.
It should be safe to set your maximum SDK version to be any release up to, but not including, v2.0.

Packages and pre-v1.0

The same applies to packages managed by the Dart team, like unittest, args, path, etc.

We have a number of packages that are pre-v1.0 – unittest is a great example.

unittest is one of our oldest and most used packages. We'd really like to lock it down and clean it up before releasing something we consider v1.0. 

If you look at the changelog for unittest, you'll see a number of breaking changes between v0.9.2 and v0.10.0.

For pre-v1.0 packages, we bump the versioning logic up a level, so for version 0.Y.Z, changes to Y are breaking and changes to Z are non-breaking.

Look again at the changelog for unittest. You'll see a number of features marked as DEPRECATED. These are things that will likely go away – stop working – in v0.11.0 of unittest.

If you want to make sure you code does not suddenly break, you should set a version constraint on unittest of something like >=0.10.0 <0.11.0.

Am I missing new hotness?

A lot of folks dislike setting maximum version constraints.

I always want to be running the new hotness!

I don't want to miss out on new features!

pub upgrade is your friend.

If you run pub upgrade from the console or within the Dart Editor, you'll see useful hints when there are newer versions of packages than what you currently specify.

You can then carefully update and check version constraints before you release.

If you want to visualize a complex package with many dependencies, check out pubviz.

Happy hacking!


pkg/unittest: shedding some cruft, getting some awesome

9:15am 7 Feb, 2014 These changes have not been released to the pub site yet.

  • If you're testing code using Future, Stream, or anything async, you'll notice a lot fewer crashes and a lot more helpful stack traces.
  • If you're subclassing Configuration, keep reading.
  • If you're using APIs on TestCase, keep reading.
  • If you're just using test, group, expect, etc. you're likely fine.
  • Update pub dependencies on unittest to includes 0.10.0 to get the new hotness. (You might have something like >=0.9.0 < 0.10.0, change it to >=0.9.0 <0.11.0)
The upcoming 0.10.0 release of unittest will have a lot of changes. Here's a copy-paste of the current changelog.
  • Each test is run in a separate Zone. This ensures that any exceptions that occur is async operations are reported back to the source test case.
  • DEPRECATED guardAsync, protectAsync0, protectAsync1, and protectAsync2
    • Running each test in a Zone addresses the need for these methods.
  • TestCase:
    • Removed properties: setUp, tearDown, testFunction
    • enabled is now get-only
    • Removed methods: pass, fail, error
  • interactive_html_config.dart has been removed.
  • runTests, tearDown, setUp, test, group, solo_test, and solo_group now throw a StateError if called while tests are running.
  • rerunTests has been removed.
These changes cover three big areas:
  • Remove unsupported APIs. The interactive test case runner hadn't been touched in a long time and it didn't support a number core test case features, like setUp and TearDown. The rerunTests function only existed to support the interactive runner and introduce a lot of weird state in unittest.
  • Make TestCase immutable. Expect more changes here. TestCase should contain the logic to run the test. The result of the run should be in another object. We're getting there.
  • Make testing async code easier. All tests are now run in a Zone. This means all any errors thrown by async operations are now funneled to the calling test case without requiring guardAsync or a protectAsyncN function (these are now deprecated).
Going forward, we're looking into more changes:
  • Remove more state from TestCase. enabled, isComplete, passed, and startTime may be removed from this class and exposed somewhere else.
  • I'm hoping to have a model where TestCase exposes Future<TestResult> run([Configuration config]) or similar.
  • More powerful ways to run unit tests, making it easy to run tests is parallel in zones, for example.
I'd like unittest to evolve to expose a very simple API that others can build on, with a layer of "easy" for those that just want to get something tested without a lot of ceremony.

Your thoughts and suggestions are welcome!

Happy hacking.


Google Compute + Docker + Dart

Follow the instructions here: http://docs.docker.io/en/master/installation/google/

Assuming the last instruction works:

sudo docker run busybox echo 'docker on GCE \o/'

Run this:

sudo docker run sethladd/docker-dart dart --version

You should see something like:

Pulling repository sethladd/docker-dart
3df1fbb95c1f: Download complete
8dbd9e392a96: Download complete
5581b213d8ed: Download complete
5242b0ef847e: Download complete
33626c0daf8f: Download complete
8b9f8f28678f: Download complete
3696f4eade8a: Download complete
a805a53d4a72: Download complete
Dart VM version: (Mon Dec  2 10:31:15 2013) on "linux_x64"

You're now running Dart via Docker on Google Compute Cloud.


Props to +Brian Dorsey and +Seth Ladd for putting the pieces together.


Joining Google

I have much less to say than the last two times I posted about changing jobs.

After 5 years freelancing, I'm going (back) corporate.

After running around the Southern US and South America, my wife and I are ready to settle back in Seattle.

After coding in C#, XAML, Ruby, and Javascript, I've finally found a development platform that I'm totally in love with: Dart. I want to make it better full time.

I'll be working in the Google office in Seattle with some great folks working on some amazing technology.

December 16 is my start date.

I can't wait.


brew install dart-editor

If you do any open source development on Mac, you're probably using Homebrew. (If you haven't heard of Homebrew, read up here.)

I've created a Homebrew formula that will install the Dart SDK, Dart Editor, and optionally content_shell for headless browser testing.

Step 1: "tap" my Homebrew repository to add the dart-editor formula to your Homebrew installation.

~/> brew tap kevmoo/kevmoo

Cloning into '/usr/local/Library/Taps/kevmoo-kevmoo'...
remote: Counting objects: 227, done.
remote: Compressing objects: 100% (154/154), done.
remote: Total 227 (delta 73), reused 225 (delta 71)
Receiving objects: 100% (227/227), 27.55 KiB | 0 bytes/s, done.
Resolving deltas: 100% (73/73), done.
Checking connectivity... done
Tapped 2 formula

Step 2: Install dart-editor. (Add the optional --with-content-shell flag if you like.)

~/> brew install dart-editor --with-content-shell

==> Downloading https://gsdview.appspot.com/dart-archive/channels/dev/release/30821/editor/darteditor-macos-x64.zip
Already downloaded: /Library/Caches/Homebrew/dart-editor-30821.zip
==> Downloading https://gsdview.appspot.com/dart-archive/channels/dev/release/30821/dartium/content_shell-macos-ia32-release.zip
Already downloaded: /Library/Caches/Homebrew/dart-editor--content_shell-30821.zip
==> Caveats
DartEditor.app was installed in:

To symlink into ~/Applications, you can do:
  brew linkapps

Note the mention of brew linkapps. This will put a symbolic link to Dart Editor.app in /Applications so it's easy to find.

What do I get?

You'll have the following binaries added to your Terminal path:
  • dart
  • dart2js
  • dartanalyzer
  • dartdoc
  • pub
  • content_shell (if you added the option)
Now you're ready to hack on Dart from the Editor and the command prompt.

Why do it this way?
  • You get Homebrew conventions for free, which includes putting part of the Dart SDK in the right spot for use from Terminal.
  • It's easy to uninstall everything.
  • It's easy to upgrade. brew update updates the dart-editor formula, too.
  • It's easy to install development versions. Once they are available, you can use brew install dart-editor --devel
Let me know if you have questions.

Pull requests are welcome!

Happy hacking!