Skip to content

Commit

Permalink
Smarter detection of the build type (#158)
Browse files Browse the repository at this point in the history
Fixes #135

Also test on Windows
  • Loading branch information
kevmoo committed May 16, 2023
1 parent fe3e2ce commit 5b722eb
Show file tree
Hide file tree
Showing 12 changed files with 88 additions and 138 deletions.
19 changes: 15 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,14 @@ jobs:
run: dart analyze --fatal-infos
if: always() && steps.install.outcome == 'success'

# Run tests on a matrix consisting of two dimensions:
# 1. OS: ubuntu-latest, (macos-latest, windows-latest)
# 2. release channel: dev
test:
needs: analyze
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
# Add macos-latest and/or windows-latest if relevant for this package.
os: [ubuntu-latest]
os: [ubuntu-latest, windows-latest]
sdk: [2.19.0, dev]
steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
Expand All @@ -62,5 +59,19 @@ jobs:
git config --global user.name "Your Name"
- run: dart test -x presubmit-only
if: always() && steps.install.outcome == 'success'

presubmit:
needs: analyze
runs-on: ubuntu-latest
strategy:
fail-fast: false
steps:
- uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
- uses: dart-lang/setup-dart@d6a63dab3335f427404425de0fbfed4686d93c4f
with:
sdk: dev
- id: install
name: Install dependencies
run: dart pub get
- run: dart test --run-skipped -t presubmit-only
if: always() && steps.install.outcome == 'success'
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
## 4.3.2-dev
## 5.0.0

- Require Dart 2.19.0
- Now chooses the "mode" (`build_runner` or Flutter) based on if the detected package is a Flutter package.

## 4.3.1

Expand Down
8 changes: 5 additions & 3 deletions lib/src/peanut.dart
Original file line number Diff line number Diff line change
Expand Up @@ -133,15 +133,17 @@ Directories: ${sourcePkg.value.join(', ')}''',
),
);

if (isFlutterSdk) {
final pkgDir = pkgNormalize(workingDir, sourcePkg.key);

if (await isFlutterPackage(pkgDir)) {
await runFlutterBuild(
pkgNormalize(workingDir, sourcePkg.key),
pkgDir,
targets,
options,
);
} else {
await runBuildRunner(
pkgNormalize(workingDir, sourcePkg.key),
pkgDir,
targets,
options,
);
Expand Down
66 changes: 2 additions & 64 deletions lib/src/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import 'dart:io';

import 'package:io/ansi.dart' as ansi;
import 'package:io/io.dart';
import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;

import 'peanut_exception.dart';
Expand Down Expand Up @@ -33,58 +32,7 @@ Future runProcess(
}
}

final String dartPath = p.join(_sdkDir, 'bin', 'dart');

/// The path to the root directory of the SDK.
final String _sdkDir = (() {
// The Dart executable is in "/path/to/sdk/bin/dart", so two levels up is
// "/path/to/sdk".
final aboveExecutable = p.dirname(p.dirname(Platform.resolvedExecutable));
assert(FileSystemEntity.isFileSync(p.join(aboveExecutable, 'version')));
return aboveExecutable;
})();

final bool isFlutterSdk = (() {
final components = p.split(Platform.resolvedExecutable);
return isFlutterSdkHeuristic(components);
})();

@visibleForTesting
bool isFlutterSdkHeuristic(List<String> path) {
// This represents the directory depth from /path/to/flutter to
// /path/to/flutter/sdk/bin/cache/dart-sdk/bin/dart.
const depth = 7;

if (path.length < depth) {
return false;
}

// Assume that the Flutter SDK is installed in a directory named 'flutter'
final flutterIndex = path.lastIndexOf('flutter');

if (flutterIndex > path.length - depth) {
return true;
}

// If no 'flutter' is found, try FVM to support that version management
// package. FVM places Flutter SDK in `~/fvm/versions/**`.
final fvmIndex = path.lastIndexOf('fvm');

// fvm puts another 2 levels to the depth, with something like
// /path/to/fvm/versions/stable.
const fvmDepth = depth + 2;

if (fvmIndex > path.length - fvmDepth) {
final versionsIndex = path.indexOf('versions', fvmIndex);
if (versionsIndex == fvmIndex + 1) {
// Path contains `fvm/versions`.
return true;
}
}

// No evidence of running from Flutter SDK.
return false;
}
String get dartPath => Platform.resolvedExecutable;

final String flutterPath = p.join(
_flutterSdkDir,
Expand All @@ -93,17 +41,7 @@ final String flutterPath = p.join(
);

/// The path to the root directory of the Flutter SDK.
String _flutterSdkDir = (() {
assert(isFlutterSdk);
// The Flutter executable is in
// "/path/to/flutter/sdk/bin/cache/dart-sdk/bin/dart", so 5 levels up is
// "/path/to/flutter/sdk".
var dir = Platform.resolvedExecutable;
for (var i = 0; i < 5; i++) {
dir = p.dirname(dir);
}
return dir;
})();
final String _flutterSdkDir = Platform.environment['FLUTTER_ROOT']!;

void checkValidOptions(String name, Set<String> config) {
if (config.isNotEmpty) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 15 additions & 5 deletions lib/src/webdev.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ import 'utils.dart';

const _args = ['pub', 'deps'];
Future _runPubDeps(String workingDirectory) async {
final processName = isFlutterSdk ? flutterPath : dartPath;

final result =
Process.runSync(processName, _args, workingDirectory: workingDirectory);
Process.runSync(dartPath, _args, workingDirectory: workingDirectory);

if (result.exitCode == 65 || result.exitCode == 66) {
throw PeanutException((result.stderr as String).trim());
Expand All @@ -37,19 +35,24 @@ Future _runPubDeps(String workingDirectory) async {
);
}
throw ProcessException(
processName,
dartPath,
_args,
'***OUT***\n${result.stdout}\n***ERR***\n${result.stderr}\n***',
exitCode,
);
}
}

Future<bool> isFlutterPackage(String pkgDir) async {
final pubspecLock = await _PubspecLock.read(pkgDir);
return pubspecLock.isFlutter;
}

Future<void> checkPubspecLock(String pkgDir) async {
final pubspecLock = await _PubspecLock.read(pkgDir);

final issues = <PackageExceptionDetails>[];
if (!isFlutterSdk) {
if (!pubspecLock.isFlutter) {
issues
..addAll(
pubspecLock.checkPackage(
Expand Down Expand Up @@ -86,6 +89,13 @@ class _PubspecLock {
return _PubspecLock(packages);
}

bool get isFlutter {
final flutterDataMap =
(_packages == null) ? null : _packages!['flutter'] as YamlMap?;

return flutterDataMap != null;
}

List<PackageExceptionDetails> checkPackage(
String pkgName,
VersionConstraint constraint, {
Expand Down
2 changes: 0 additions & 2 deletions peanut.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
directories:
- example

post-build-dart-script: tool/clean_output.dart

builder-options:
build_web_compilers|entrypoint:
dart2js_args:
Expand Down
4 changes: 2 additions & 2 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: peanut
version: 4.3.2-dev
version: 5.0.0
description: >-
Update your GitHub gh-pages branch with the compiled output of your Dart web
app. Supports 'pub build' and the new 'pub run build_runner'.
Expand All @@ -11,7 +11,7 @@ dependencies:
args: ^2.0.0
build_cli_annotations: ^2.0.0
checked_yaml: ^2.0.0
git: ^2.0.0
git: ^2.2.1
glob: ^2.0.0
io: ^1.0.0
json_annotation: ^4.8.1
Expand Down
74 changes: 42 additions & 32 deletions test/cli_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ Arguments:
-h, --help Prints usage information.
--version Print the current version.''';

String get _someFilePath => p.join(d.sandbox, 'some_file.yaml');

void main() {
test('help', () async {
final proc = await _runPeanut(['--help']);
Expand All @@ -65,11 +67,15 @@ void main() {
await proc.shouldExit(0);
});

test('readme', () {
final content = File('README.md').readAsStringSync();
test(
'readme',
onPlatform: {'windows': const Skip()},
() {
final content = File('README.md').readAsStringSync();

expect(content, contains(_output));
});
expect(content, contains(_output));
},
);

test('bad flag', () async {
final proc = await _runPeanut(['--bob']);
Expand Down Expand Up @@ -138,10 +144,10 @@ The follow options are not supported with a build_runner build:
expectParseOptionsThrows(
[
'--builder-options',
p.join(d.sandbox, 'some_file.yaml'),
_someFilePath,
],
'''
FormatException: "${p.join(d.sandbox, 'some_file.yaml')}" is neither a path to a YAML file nor a YAML map.''',
FormatException: "$_someFilePath" is neither a path to a YAML file nor a YAML map.''',
);
});

Expand All @@ -150,7 +156,7 @@ FormatException: "${p.join(d.sandbox, 'some_file.yaml')}" is neither a path to a

final options = parseOptions([
'--builder-options',
p.join(d.sandbox, 'some_file.yaml'),
_someFilePath,
]);

expect(options.builderOptions, hasLength(1));
Expand All @@ -163,10 +169,10 @@ FormatException: "${p.join(d.sandbox, 'some_file.yaml')}" is neither a path to a
expectParseOptionsThrows(
[
'--builder-options',
p.join(d.sandbox, 'some_file.yaml'),
_someFilePath,
],
'''
FormatException: "${p.join(d.sandbox, 'some_file.yaml')}" is neither a path to a YAML file nor a YAML map.''',
FormatException: "$_someFilePath" is neither a path to a YAML file nor a YAML map.''',
);
});

Expand All @@ -176,39 +182,43 @@ FormatException: "${p.join(d.sandbox, 'some_file.yaml')}" is neither a path to a
expectParseOptionsThrows(
[
'--builder-options',
p.join(d.sandbox, 'some_file.yaml'),
_someFilePath,
],
'FormatException: The value for "bob" was not a Map.',
);
});

test('invalid yaml format', () async {
await d.file('some_file.yaml', '{').create();

expect(
() => parseOptions(
[
'--builder-options',
p.join(d.sandbox, 'some_file.yaml'),
],
),
throwsA(
isA<ParsedYamlException>().having(
(e) {
printOnFailure(e.formattedMessage ?? '');
return e.formattedMessage;
},
'formattedMessage',
'''
line 1, column 2 of ${p.join(d.sandbox, 'some_file.yaml')}: Expected node content.
test(
'invalid yaml format',
onPlatform: {'windows': const Skip('path weirdness')},
() async {
await d.file('some_file.yaml', '{').create();

expect(
() => parseOptions(
[
'--builder-options',
_someFilePath,
],
),
throwsA(
isA<ParsedYamlException>().having(
(e) {
printOnFailure(e.formattedMessage ?? '');
return e.formattedMessage;
},
'formattedMessage',
'''
line 1, column 2 of $_someFilePath: Expected node content.
1 │ {
│ ^
╵''',
),
),
),
);
});
);
},
);
});
});
}
Expand Down
1 change: 1 addition & 0 deletions test/ensure_build_test.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
@Timeout.factor(2)
@Tags(['presubmit-only'])
@TestOn('!windows')
library;

import 'package:build_verify/build_verify.dart';
Expand Down
23 changes: 0 additions & 23 deletions test/flutter_test.dart

This file was deleted.

0 comments on commit 5b722eb

Please sign in to comment.