From 6fb162abdd2bdaab8d97cdfa1132292b01451abf Mon Sep 17 00:00:00 2001 From: Kevin Moore Date: Fri, 23 Mar 2018 19:51:07 -0700 Subject: [PATCH] Use `pub deps` to validate target directory Much more robust than just checking for a .packages file --- webdev/CHANGELOG.md | 1 + webdev/lib/src/pubspec.dart | 25 ++++++-- webdev/test/integration_test.dart | 100 +++++++++++++++++++++++++++--- 3 files changed, 114 insertions(+), 12 deletions(-) diff --git a/webdev/CHANGELOG.md b/webdev/CHANGELOG.md index 10354fe76..d607bad34 100644 --- a/webdev/CHANGELOG.md +++ b/webdev/CHANGELOG.md @@ -2,6 +2,7 @@ - Remove check for `build_web_compilers`. Allows general support for `build_runner` from tools. +- Use `pub deps` to validate target directory. ## 0.1.1 diff --git a/webdev/lib/src/pubspec.dart b/webdev/lib/src/pubspec.dart index c74596c29..66a30de90 100644 --- a/webdev/lib/src/pubspec.dart +++ b/webdev/lib/src/pubspec.dart @@ -37,13 +37,28 @@ class PackageExceptionDetails { String toString() => [error, description].join('\n'); } -Future checkPubspecLock() async { - var file = new File('pubspec.lock'); - if (!file.existsSync()) { - throw new PackageException._([PackageExceptionDetails.noPubspecLock]); +Future _runPubDeps() async { + var result = Process.runSync('pub', ['deps']); + + if (result.exitCode == 65 || result.exitCode == 66) { + throw new PackageException._( + [new PackageExceptionDetails._((result.stderr as String).trim())]); + } + + if (result.exitCode != 0) { + throw new ProcessException( + 'pub', + ['deps'], + '***OUT***\n${result.stdout}\n***ERR***\n${result.stderr}\n***', + exitCode); } +} + +Future checkPubspecLock() async { + await _runPubDeps(); - var pubspecLock = loadYaml(await file.readAsString()) as YamlMap; + var pubspecLock = + loadYaml(await new File('pubspec.lock').readAsString()) as YamlMap; var packages = pubspecLock['packages'] as YamlMap; diff --git a/webdev/test/integration_test.dart b/webdev/test/integration_test.dart index 0f179ab54..2d8f2d148 100644 --- a/webdev/test/integration_test.dart +++ b/webdev/test/integration_test.dart @@ -2,6 +2,7 @@ // 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. +import 'dart:async'; import 'dart:io'; import 'package:path/path.dart' as p; @@ -45,6 +46,10 @@ A dependency on `build_runner` was not found.''')); group('should fail when `build_runner` is the wrong version', () { for (var version in ['0.7.13+1', '0.9.0']) { test(version, () async { + await d.file('pubspec.yaml', ''' +name: sample +''').create(); + await d.file('pubspec.lock', ''' # Copy-pasted from a valid run packages: @@ -57,6 +62,9 @@ packages: version: "$version" ''').create(); + await d.file('.packages', ''' +''').create(); + var process = await TestProcess.start('dart', [_webdevBin, 'build'], workingDirectory: d.sandbox); @@ -71,7 +79,38 @@ packages: } }); - test('should fail gracefully if there is no .packages file', () async { + test('no pubspec.yaml', () async { + var process = await TestProcess.start('dart', [_webdevBin, 'build'], + workingDirectory: d.sandbox); + + var output = await process.stdoutStream().join('\n'); + + expect(output, contains('Could not run in the current directory.')); + expect(output, contains('Could not find a file named "pubspec.yaml"')); + await process.shouldExit(78); + }); + + test('pubspec.yaml, no pubspec.lock', () async { + await d.file('pubspec.yaml', ''' +name: sample +''').create(); + + var process = await TestProcess.start('dart', [_webdevBin, 'build'], + workingDirectory: d.sandbox); + + var output = await process.stdoutStream().join('\n'); + + expect(output, contains('Could not run in the current directory.')); + expect(output, + contains('No pubspec.lock file found, please run "pub get" first.')); + await process.shouldExit(78); + }); + + test('pubspec.yaml, pubspec.lock, no .packages', () async { + await d.file('pubspec.yaml', ''' +name: sample +''').create(); + await d.file('pubspec.lock', ''' # Copy-pasted from a valid run packages: @@ -87,14 +126,19 @@ packages: var process = await TestProcess.start('dart', [_webdevBin, 'build'], workingDirectory: d.sandbox); - await expectLater( - process.stdout, emits('Could not run in the current directory.')); - await expectLater(process.stdout, - emits('A `.packages` file does not exist in the target directory.')); + var output = await process.stdoutStream().join('\n'); + + expect(output, contains('Could not run in the current directory.')); + expect(output, + contains('No .packages file found, please run "pub get" first.')); await process.shouldExit(78); }); test('should fail gracefully if there is an isolate error', () async { + await d.file('pubspec.yaml', ''' +name: sample +''').create(); + await d.file('pubspec.lock', ''' # Copy-pasted from a valid run packages: @@ -112,11 +156,53 @@ packages: var process = await TestProcess.start('dart', [_webdevBin, 'build'], workingDirectory: d.sandbox); - await expectLater( - process.stdout, emits('An unexpected exception has occurred.')); + var output = await process.stdoutStream().join('\n'); + + expect(output, contains('An unexpected exception has occurred.')); + + // The isolate will fail - broken .packages file + expect(output, contains('Unable to spawn isolate')); await process.shouldExit(70); }); + test('should fail if there has been a dependency change', () async { + await d.file('pubspec.lock', ''' +# Copy-pasted from a valid run +packages: + build_runner: + dependency: "direct main" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.0" +''').create(); + + await d.file('.packages', '').create(); + + // Ensure there is a noticeable delta in the creation times + await new Future.delayed(const Duration(milliseconds: 500)); + + await d.file('pubspec.yaml', ''' +name: sample +dependencies: + args: ^1.0.0 +''').create(); + + var process = await TestProcess.start('dart', [_webdevBin, 'build'], + workingDirectory: d.sandbox); + + var output = await process.stdoutStream().join('\n'); + + expect(output, contains('Could not run in the current directory.')); + expect( + output, + contains( + 'The pubspec.yaml file has changed since the pubspec.lock file ' + 'was generated, please run "pub get" again.')); + await process.shouldExit(78); + }); + test('should succeed with valid configuration', () async { var exampleDirectory = p.absolute(p.join(p.current, '..', 'example')); var process = await TestProcess.start('pub', ['get'],