Saturday, September 28, 2013

Strike Two: Using Big Dart Package Patches


My first attempt at working with a large Dart patch was not quite as smooth as I would have liked. The problem is that the patch spans several Dart packages. Applying the patch was easy enough, but getting my local code to work with the local packages resulted in something akin to dependency hell:



Those are just a few of the changes that I needed to make—not only to the packages that are directly impacted by the patch—but also to the packages that rely on the same code. The problem is that Dart's Pub package system will not allow the same packages to be installed from two different sources (e.g. pub.dartlang.org and the filesystem).

It might be nice for Pub to defer an “any” constraint in favor of a “path” one. That is, if the various packages in the dependency tree includes a bunch of mdv: any dependency and a single mdv: path: /home/chris/repos/dart/dart/pkg/mdv dependency, then the latter could be used everywhere. No matter, this is an edge case for an admittedly early-stage tool like Pub. In the meantime, how might I better handle development in this case?

I try switching my project's dependencies back to the default pub.dartlang.org by reverting the constraints to “any” in pubspec.yaml:
name: ice_code_editor
# ...
dependencies:
  # ...
  polymer: any
After a pub install, a quick check of the project's packages directory shows that the three packages that were addressed by the original patch—polymer, custom_element, and observe—are now coming from pub.dartlang.org:
➜  ice-code-editor git:(polymer) ✗ ls -l packages/{polymer,custom_element,observe}
lrwxrwxrwx 1 chris chris 71 Sep 28 20:07 packages/custom_element -> 
    /home/chris/.pub-cache/hosted/pub.dartlang.org/custom_element-0.7.5/lib
lrwxrwxrwx 1 chris chris 64 Sep 28 20:07 packages/observe -> 
    /home/chris/.pub-cache/hosted/pub.dartlang.org/observe-0.7.5/lib
lrwxrwxrwx 1 chris chris 64 Sep 28 20:07 packages/polymer -> 
    /home/chris/.pub-cache/hosted/pub.dartlang.org/polymer-0.7.5/lib
I remove the symbolic links to the cached, hosted versions of those packages, replacing them with my modified local versions instead:
➜  ice-code-editor git:(polymer) ✗ cd packages 
➜  packages git:(polymer) ✗ rm {polymer,observe,custom_element}
➜  packages git:(polymer) ✗ ln -s ~/repos/dart/dart/pkg/polymer/lib polymer
➜  packages git:(polymer) ✗ ln -s ~/repos/dart/dart/pkg/observe/lib observe    
➜  packages git:(polymer) ✗ ln -s ~/repos/dart/dart/pkg/custom_element/lib custom_element
That seems to work. At the very least, the built-in pub serve web server starts up without complaint:
➜  ice-code-editor git:(polymer) ✗ pub serve
Serving ice_code_editor on http://localhost:8080
Build completed successfully
Sadly, appearances are deceiving in this case. The updated polymer_element.dart file is nearly empty:
➜  ice-code-editor git:(polymer) ✗ cat packages/polymer/polymer_element.dart
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library polymer.polymer_element;

export 'polymer.dart' show PolymerElement, registerPolymerElement;

➜  ice-code-editor git:(polymer) ✗ cat web/packages/polymer/polymer_element.dart
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library polymer.polymer_element;

export 'polymer.dart' show PolymerElement, registerPolymerElement;
But when I curl for that resource, I find the old version of the resource:
➜  ice-code-editor git:(polymer) ✗ curl http://localhost:8080/packages/polymer/polymer_element.dart
// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library polymer.polymer_element;

import 'dart:async';
import 'dart:html';
import 'dart:mirrors';
import 'dart:js' as js;

import 'package:custom_element/custom_element.dart';
import 'package:mdv/mdv.dart' show NodeBinding;
import 'package:observe/observe.dart';
import 'package:observe/src/microtask.dart';
import 'package:polymer_expressions/polymer_expressions.dart';

import 'src/utils.dart' show toCamelCase, toHyphenedName;

/**
 * Registers a [PolymerElement]. This is similar to [registerCustomElement]
 * but it is designed to work with the `<element>` element and adds additional
 * features.
 */
void registerPolymerElement(String localName, PolymerElement create()) {

Much more follows...
Bother. It would seem that pub serve is reading pubspec.lock in order to figure out where to find its files—completely ignoring the symbolic links in the packages directory.

Manually manipulating symbolic links in the packages directory is already pretty far off the rails, but before abandoning the effort entirely, I try modifying the pubspec.lock file that is generated by pub install.

Unfortunately, when I try out the Pub server, it notices my modifications and overwrites them:
➜  ice-code-editor git:(polymer) ✗ pub serve
Dependencies have changed, installing...
Resolving dependencies......................
Dependencies installed!
Serving ice_code_editor on http://localhost:8080
Ah well, it was worth a try.

It is a bummer, but pubspec.yaml dependency hell is currently the only way that I can see to try out existing projects with new core-package changes.

Day #888

No comments:

Post a Comment