Skip to content

Drop build and serve #1871

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Apr 17, 2018
Merged

Drop build and serve #1871

merged 25 commits into from
Apr 17, 2018

Conversation

natebosch
Copy link
Member

@natebosch natebosch commented Apr 14, 2018

Closes #1857

  • Drop lib/src/{barback,dartdevc,asset} and relevant tests
  • Add lib/src/asset/id.dart since non-building code uses this type
    from barback.
  • Clean up analyzer errors, droping any code paths that relate to
    dealing with Transformers, for example the run command's ability to
    run with transformed code, or any parsing and plumbing for transformer
    config.
  • Clean up any tests that were checking behavior of transformers or the
    build or serve command.
  • Remove any dependencies for which I could no longer find an import.

- Drop `lib/src/{barback,datdevc,asset}` and relevant tests
- Add `lib/src/asset/id.dart` since non-building code uses this type
  from barback.
- Clean up analyzer errors, droping any code paths that relate to
  dealing with Transformers, for example the `run` command's ability to
  run with transformed code, or any parsing and plumbing for transformer
  config.
- Clean up any tests that were checking behavior of transformers or the
  build or serve command.
- Remove any dependencies for which I could no longer find an import.
@natebosch
Copy link
Member Author

Note that a pub run on a package which does expected to be transformed will now likely fail in mysterious ways since it will be run directly without transformers. I tried to see if we could cheaply keep around just enough of the code paths to support a warning for this case but it didn't seem like it would be worth doing.

@natebosch
Copy link
Member Author

The build or serve commands now exit(1) after printing in red to stderr:

Dart 2 has a new build system. Learn how to migrate from pub build and
pub serve: https://webdev.dartlang.org/dart-2

- Hide the build and serve commands
- Remove mode option
@kevmoo
Copy link
Member

kevmoo commented Apr 14, 2018

one failing test – and one unformatted file. Nice...

@natebosch
Copy link
Member Author

@nex3 - can you help me understand how this test works?
https://github.com/dart-lang/pub/blob/master/test/global/run/uses_old_lockfile_test.dart

I see that it's setting up a fake package for foo. How does the import to bar work here? I don't see where bar.main() is getting set up with some behavior. The failure Could not find bin/script.dart in package foo. makes sense to me, how did this work before?

@nex3
Copy link
Member

nex3 commented Apr 16, 2018

Will do a full review in a bit, but:

Note that a pub run on a package which does expected to be transformed will now likely fail in mysterious ways since it will be run directly without transformers. I tried to see if we could cheaply keep around just enough of the code paths to support a warning for this case but it didn't seem like it would be worth doing.

I think this is fine. I think the vast majority of users of transformers in practice used them for building web apps.

@nex3 - can you help me understand how this test works?
https://github.com/dart-lang/pub/blob/master/test/global/run/uses_old_lockfile_test.dart

I see that it's setting up a fake package for foo. How does the import to bar work here? I don't see where bar.main() is getting set up with some behavior. The failure Could not find bin/script.dart in package foo. makes sense to me, how did this work before?

This tries to simulate what pub global activate would have created with older pub versions—the foo package isn't fake, it's just added to the cache manually via pub cache add on line 26.

The bar import worked because pub would load up an asset environment every time it ran an executable. The right behavior now is probably to detect an executable without a snapshot and try to compile that snapshot.

@natebosch
Copy link
Member Author

The bar import worked because pub would load up an asset environment every time it ran an executable.

If I'm understanding the test correctly it seems to expect that the asset environment would have successfully provided that file, allow the pub run to execute the script, and somehow make bar.main() return "bar 1.0.0"

Or am I misunderstanding this?

@natebosch
Copy link
Member Author

natebosch commented Apr 16, 2018

Ah, Jake pointed me to where the magic file is created

@natebosch
Copy link
Member Author

The immediate problem is that without the Barback asset environment we only know how to find a package if it has a .packages file.

I think the "1.6-style lockfile" for global packages might only work through the asset environment.

Before I spend time on a fix - is this something we feel we need to continue to support?

This is not worth supporting
@nex3
Copy link
Member

nex3 commented Apr 16, 2018

The immediate problem is that without the Barback asset environment we only know how to find a package if it has a .packages file.

I think the "1.6-style lockfile" for global packages might only work through the asset environment.

Right. Before we started creating snapshots (which was well after 1.6), all pub global run invocations used the asset environment, so they weren't set up to work in any other way.

Before I spend time on a fix - is this something we feel we need to continue to support?

If it's a huge amount of effort you could drop it, but I think all you should need to do is something like

if (!fileExists(snapshotPath)) await _precompileExecutables(package);

There's a lot of psychological value for users in guaranteeing that the package manager will never choke on data it itself created, even in edge cases like this.

@natebosch
Copy link
Member Author

If it's a huge amount of effort you could drop it, but I think all you should need to do is something like

if (!fileExists(snapshotPath)) await _precompileExecutables(package);

_precompileExecutables would end up going through snapshot which requires a .packages or packages/ as well (I don't know what "a package spec is inferred from the executable's location" means, but I suspect it won't happen since we're calling dart which doesn't understand package_name.lock files AFAIK).

I think in order to support this we'd need to rewrite some of the AssetEnvironment stuff without barback.

Copy link
Member

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Real excited to see this stuff get deleted!

// BSD-style license that can be found in the LICENSE file.

/// Like the AssetId class from barback but without the barback dependency.
class AssetId {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to get rid of this entirely? Looking through the remaining uses, it seems like almost all of them exist in contexts where the package is determined by context, so you could just use the executable name.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that at first and hit at least one case where we were storing a collection of AssetIds and lost context of their associated packages.

I can take another look, but I'd prefer to do that in a new PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I overestimated the scope. I replaced id with a packageName and pathInPackage argument in the snapshot method, but everything else was, as you pointed out, already in a context where we had the package name.

/// cached, this returns the cached information. It also wraps the package's
/// pubspec to report no transformers, since the transformations have all been
/// applied already.
/// cached, this returns the cached information.
class CachedPackage extends Package {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary anymore—there's nothing for pub to precompile in the lib directory.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return result;
log.error(log.red("Dart 2 has a new build system. Learn how to migrate "
"from ${log.bold('pub build')} and\n"
"${log.bold('pub serve')}: https://webdev.dartlang.org/dart-2\n"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: use fail() instead of log.error() and exit().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

GlobalRunCommand() {
argParser.addFlag("checked",
abbr: "c", help: "Enable runtime type checks and assertions.");
argParser.addOption("mode",
defaultsTo: "release", help: 'Mode to run transformers in.');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to give build and serve helpful error messages, we might as well do so for --mode as well (also below).

@@ -8,116 +8,13 @@ import 'dart:io';
import 'dart:isolate';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like isPart() in this file is no longer used.

Copy link
Member Author

@natebosch natebosch Apr 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed along with runInIsolate and some (newly?) unused methods from utils.dart

});
}

//// Precompiles [executables] to snapshots from the filesystem.
Future _precompileExecutablesWithoutBarback(
Map<String, List<AssetId>> executables) {
Future _precompileExecutables(Map<String, List<AssetId>> executables) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, the package names in the executables map are totally redundant; this could just be Map<String, List<String>>. The only reason we represented executables as AssetIds before was for convenience when passing them to Barback.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, I started down that path and hit one place where it wasn't redundant and restructuring that felt like it was snowballing.

@@ -245,82 +243,6 @@ class Pubspec {

Map<String, Feature> _features;

/// The configurations of the transformers to use for this package.
List<Set<TransformerConfig>> get transformers {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add validators that produce warnings when trying to publish packages that include a transformers field or a web.compiler field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we do that in a followup?

new Term(
_systemCache.sources.hosted.refFor(name).withConstraint(constraint),
false)
], IncompatibilityCause.pubDependency));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also remove IncompatibilityCause.pubDependency and its other referents.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -1,55 +0,0 @@
// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should still behave nicely with old-style packages—ideally recompile them, if not that then create a .packages file, or at the very least produce a useful error message telling users how to fix the problem.

/// pub.
Future serveBarback() {
return servePackages((builder) {
builder.serveRealPackage('barback');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can delete serveRealPackage() as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@nex3
Copy link
Member

nex3 commented Apr 16, 2018

_precompileExecutables would end up going through snapshot which requires a .packages or packages/ as well (I don't know what "a package spec is inferred from the executable's location" means, but I suspect it won't happen since we're calling dart which doesn't understand package_name.lock files AFAIK).

I suppose that's true, but you can generate a new .packages file really easily given the lockfile.

@natebosch
Copy link
Member Author

Ok, I've got a change that passes the test. bcc70cd

It requires passing the system cache through, we could maybe do this check earlier though to avoid it introducing a new import in executable.dart

Copy link
Member

@nex3 nex3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've got a change that passes the test. bcc70cd

It requires passing the system cache through, we could maybe do this check earlier though to avoid it introducing a new import in executable.dart

LGTM. I don't think adding a new import is a big cost, but I realized you'd still have to check to make sure that it's immutable and fall back to running from source if it's not, so just writing the .packages file is probably fine. Make sure to re-add the test, though!

if (!fileExists(entrypoint.packagesFile)) {
if (!isGlobal) return null;
await writeTextFile(
entrypoint.packagesFile, entrypoint.lockFile.packagesFile(cache));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment indicating why a global entrypoint without a .packages file would exist.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@nex3
Copy link
Member

nex3 commented Apr 17, 2018

Give me a poke when you want me to take another look.

@natebosch
Copy link
Member Author

natebosch commented Apr 17, 2018

I think I have addressed all feedback except for:

  • Validation that there is no transformers or web compiler config on publish
  • Warning when using the --mode argument to run

If you're OK with adding validation in a follow up this is ready for another review.

@jakemac53
Copy link
Contributor

jakemac53 commented Apr 17, 2018

Fwiw - I am going to forgo doing an actual review here since @nex3 is more familiar with the codebase anyways and its quite large.

I will note that when it comes to supporting the old lockfiles for pub run the chance of those globally activated packages being able to run with old package versions on the Dart 2 sdk is essentially zero anyways, so breaking compatibility with them is perfectly fine with me. We should just detect the situation and ask people to re-activate the package.

Future snapshot(Uri executableUrl, String snapshotPath,
{Uri packagesFile, AssetId id}) async {
var name = log.bold(id == null
{Uri packagesFile, String packageName, String pathInPackage}) async {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider replacing the packageName and pathInPackage parameters with an name parameter and make the caller responsible for deciding what that name could look like. Then the first line could just be name ??= executableUrl.toString().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// helpful for the subprocess to be able to spawn Dart with
// Platform.executableArguments and have that work regardless of the working
// directory.
Uri packageConfig = p.toUri(p.absolute(entrypoint.packagesFile));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: don't type-annotate local variables.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

DeprecatedFieldsValidator(Entrypoint entrypoint) : super(entrypoint);

Future validate() {
return new Future.sync(() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: I'd just make the method async.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

return new Future.sync(() {
if (entrypoint.root.pubspec.fields.containsKey('transformers')) {
warnings.add('Your pubpsec.yaml includes a "transformers" section which'
' is no longer used and may be removed');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: warnings should end with a period.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


main() {
setUp(d.validPackage.create);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good to add a test that this doesn't warn for a pubspec that doesn't have either deprecated field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@nex3
Copy link
Member

nex3 commented Apr 17, 2018

celebrating

@natebosch natebosch merged commit 5ca86eb into master Apr 17, 2018
@natebosch natebosch deleted the kill-build branch April 17, 2018 21:28
@denniskaselow
Copy link

denniskaselow commented Apr 24, 2018

I don't want to ruin the party, but running pub get/upgrade from master now hangs on windows after commit 5ca86eb.

It does
IO : Spawning "cmd /c dart --packages=.packages --snapshot=.\.dart_tool/pub\bin\test\bin\test.dart.snapshot file:///C:/Users/dennis/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/test-0.12.34/bin%5Ctest.dart" in F:\Programming\workspaces\dart\dartemis_builder\.

instead of

IO : Spawning "cmd /c dart --packages=.packages --snapshot=.\.dart_tool/pub\bin\test\bin\test.dart.snapshot file:///C:/Users/dennis/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/test-0.12.34/bin/test.dart" in F:\Programming\workspaces\dart\dartemis_builder\.

(notice the encoded \ (%5C) instead of a /.

Stumbled over it, when I tested the fix for #1756.

@natebosch
Copy link
Member Author

This is not synced in the SDK so it is not published. What configuration are you using such that you are running this version of pub?

@denniskaselow
Copy link

denniskaselow commented Apr 24, 2018

I cloned the repository to test that other bugfix and used dart bin/pub.dart to run it.

I dove in a bit deeper, and the problem for the %5C problem is 5ca86eb. It changes what precompiling executables does.
If I go back to 711f515 dart bin/pub.dart runs just fine.

@kevmoo
Copy link
Member

kevmoo commented Apr 24, 2018

@denniskaselow – could we open a separate issue for this? in the pub repo...

Please be clear on the commit SHA you're hitting the issue at...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants