Unverified Commit 899a29f8 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Reorganize and clarify API doc generator (#132353)

## Description

This cleans up a lot of issues with the API doc generation.

Here are the main changes:
 - Rename `dartdoc.dart` to `create_api_docs.dart`
 - Move the bulk of the operations out of `dev/bots/docs.sh` into `create_api_docs.dart`.
 - Delete `dashing_postprocess.dart` and `java_and_objc.dart` and incorporate those operations into `create_api_docs.dart`.
 - Refactor the doc generation into more understandable classes
 - Bump the snippets tool version to 0.4.0 (the latest one)
 - Centralize the information gathering about the Flutter repo into the new `FlutterInformation` class.
 - Clean up the directory handling, and convert to using the `file` package for all file and directory paths.
 - Add an `--output` option to docs.sh that specifies the location of the output ZIP file containing the docs.
   - Defaults to placing the output in `dev/docs/api_docs.zip` (i.e. where the previous code generates the file).
 - Moved all document generation into a temporary folder that is removed once the documents are generated, to avoid VSCode and other IDEs trying to index the thousands of HTML and JS files in the docs output.
 - Updated pubspec dependencies.

## Tests
 - Added tests for doc generation.
parent 301577a3
......@@ -16,102 +16,13 @@ function script_location() {
cd -P "$(dirname "$script_location")" >/dev/null && pwd
}
function generate_docs() {
# Install and activate dartdoc.
# When updating to a new dartdoc version, please also update
# `dartdoc_options.yaml` to include newly introduced error and warning types.
"$DART" pub global activate dartdoc 6.3.0
# Install and activate the snippets tool, which resides in the
# assets-for-api-docs repo:
# https://github.com/flutter/assets-for-api-docs/tree/master/packages/snippets
"$DART" pub global activate snippets 0.3.1
# This script generates a unified doc set, and creates
# a custom index.html, placing everything into dev/docs/doc.
(cd "$FLUTTER_ROOT/dev/tools" && "$FLUTTER" pub get)
(cd "$FLUTTER_ROOT/dev/tools" && "$DART" pub get)
(cd "$FLUTTER_ROOT" && "$DART" --disable-dart-dev --enable-asserts "$FLUTTER_ROOT/dev/tools/dartdoc.dart")
(cd "$FLUTTER_ROOT" && "$DART" --disable-dart-dev --enable-asserts "$FLUTTER_ROOT/dev/tools/java_and_objc_doc.dart")
}
# Zip up the docs so people can download them for offline usage.
function create_offline_zip() {
# Must be run from "$FLUTTER_ROOT/dev/docs"
echo "$(date): Zipping Flutter offline docs archive."
rm -rf flutter.docs.zip doc/offline
(cd ./doc; zip -r -9 -q ../flutter.docs.zip .)
}
# Generate the docset for Flutter docs for use with Dash, Zeal, and Velocity.
function create_docset() {
# Must be run from "$FLUTTER_ROOT/dev/docs"
# Must have dashing installed: go get -u github.com/technosophos/dashing
# Dashing produces a LOT of log output (~30MB), so we redirect it, and just
# show the end of it if there was a problem.
echo "$(date): Building Flutter docset."
rm -rf flutter.docset
# If dashing gets stuck, Cirrus will time out the build after an hour, and we
# never get to see the logs. Thus, we run it in the background and tail the logs
# while we wait for it to complete.
dashing_log=/tmp/dashing.log
dashing build --source ./doc --config ./dashing.json > $dashing_log 2>&1 &
dashing_pid=$!
wait $dashing_pid && \
cp ./doc/flutter/static-assets/favicon.png ./flutter.docset/icon.png && \
"$DART" --disable-dart-dev --enable-asserts ./dashing_postprocess.dart && \
tar cf flutter.docset.tar.gz --use-compress-program="gzip --best" flutter.docset
if [[ $? -ne 0 ]]; then
>&2 echo "Dashing docset generation failed"
tail -200 $dashing_log
exit 1
fi
}
function deploy_docs() {
case "$LUCI_BRANCH" in
master)
echo "$(date): Updating $LUCI_BRANCH docs: https://master-api.flutter.dev/"
# Disable search indexing on the master staging site so searches get only
# the stable site.
echo -e "User-agent: *\nDisallow: /" > "$FLUTTER_ROOT/dev/docs/doc/robots.txt"
;;
stable)
echo "$(date): Updating $LUCI_BRANCH docs: https://api.flutter.dev/"
# Enable search indexing on the master staging site so searches get only
# the stable site.
echo -e "# All robots welcome!" > "$FLUTTER_ROOT/dev/docs/doc/robots.txt"
;;
*)
>&2 echo "Docs deployment cannot be run on the $LUCI_BRANCH branch."
exit 0
esac
}
# Move the offline archives into place, after all the processing of the doc
# directory is done. This avoids the tools recursively processing the archives
# as part of their process.
function move_offline_into_place() {
# Must be run from "$FLUTTER_ROOT/dev/docs"
echo "$(date): Moving offline data into place."
mkdir -p doc/offline
mv flutter.docs.zip doc/offline/flutter.docs.zip
du -sh doc/offline/flutter.docs.zip
if [[ "$LUCI_BRANCH" == "stable" ]]; then
echo -e "<entry>\n <version>${FLUTTER_VERSION_STRING}</version>\n <url>https://api.flutter.dev/offline/flutter.docset.tar.gz</url>\n</entry>" > doc/offline/flutter.xml
else
echo -e "<entry>\n <version>${FLUTTER_VERSION_STRING}</version>\n <url>https://master-api.flutter.dev/offline/flutter.docset.tar.gz</url>\n</entry>" > doc/offline/flutter.xml
fi
mv flutter.docset.tar.gz doc/offline/flutter.docset.tar.gz
du -sh doc/offline/flutter.docset.tar.gz
}
# So that users can run this script from anywhere and it will work as expected.
SCRIPT_LOCATION="$(script_location)"
# Sets the Flutter root to be "$(script_location)/../..": This script assumes
# that it resides two directory levels down from the root, so if that changes,
# then this line will need to as well.
FLUTTER_ROOT="$(dirname "$(dirname "$SCRIPT_LOCATION")")"
export FLUTTER_ROOT
echo "$(date): Running docs.sh"
......@@ -124,31 +35,106 @@ FLUTTER_BIN="$FLUTTER_ROOT/bin"
DART_BIN="$FLUTTER_ROOT/bin/cache/dart-sdk/bin"
FLUTTER="$FLUTTER_BIN/flutter"
DART="$DART_BIN/dart"
export PATH="$FLUTTER_BIN:$DART_BIN:$PATH"
PATH="$FLUTTER_BIN:$DART_BIN:$PATH"
# Make sure dart is installed by invoking Flutter to download it.
# This also creates the 'version' file.
FLUTTER_VERSION=$("$FLUTTER" --version --machine)
# Make sure dart is installed by invoking Flutter to download it if it is missing.
# Also make sure the flutter command is ready to run before capturing output from
# it: if it has to rebuild itself or something, it'll spoil our JSON output.
"$FLUTTER" > /dev/null 2>&1
FLUTTER_VERSION="$("$FLUTTER" --version --machine)"
export FLUTTER_VERSION
FLUTTER_VERSION_STRING=$(cat "$FLUTTER_ROOT/version")
# If the pub cache directory exists in the root, then use that.
FLUTTER_PUB_CACHE="$FLUTTER_ROOT/.pub-cache"
if [[ -d "$FLUTTER_PUB_CACHE" ]]; then
# This has to be exported, because pub interprets setting it to the empty
# string in the same way as setting it to ".".
export PUB_CACHE="${PUB_CACHE:-"$FLUTTER_PUB_CACHE"}"
PUB_CACHE="${PUB_CACHE:-"$FLUTTER_PUB_CACHE"}"
export PUB_CACHE
fi
generate_docs
# Skip publishing docs for PRs and release candidate branches
if [[ -n "$LUCI_CI" && -z "$LUCI_PR" ]]; then
(cd "$FLUTTER_ROOT/dev/docs"; create_offline_zip)
(cd "$FLUTTER_ROOT/dev/docs"; create_docset)
(cd "$FLUTTER_ROOT/dev/docs"; move_offline_into_place)
deploy_docs
fi
OUTPUT_DIR=$(mktemp -d /tmp/dartdoc.XXXXX)
DOC_DIR="$OUTPUT_DIR/doc"
function usage() {
echo "Usage: $(basename "${BASH_SOURCE[0]}") [--keep-temp] [--output <output.zip>]"
echo ""
echo " --keep-temp Do not delete the temporary output directory created while generating docs."
echo " Normally the script deletes the temporary directory after generating the"
echo " output ZIP file."
echo " --output <output.zip> specifies where the output ZIP file containing the documentation data"
echo " will be written."
echo ""
}
function parse_args() {
local arg
local args=()
KEEP_TEMP=0
DESTINATION="$FLUTTER_ROOT/dev/docs/api_docs.zip"
while (( "$#" )); do
case "$1" in
--help)
usage
exit 0
;;
--keep-temp)
KEEP_TEMP=1
;;
--output)
DESTINATION="$2"
shift
;;
*)
args=("${args[@]}" "$1")
;;
esac
shift
done
if [[ ${#args[@]} != 0 ]]; then
>&2 echo "ERROR: Unknown arguments: ${args[@]}"
usage
exit 1
fi
}
function generate_docs() {
# Install and activate dartdoc.
# When updating to a new dartdoc version, please also update
# `dartdoc_options.yaml` to include newly introduced error and warning types.
"$DART" pub global activate dartdoc 6.3.0
# Install and activate the snippets tool, which resides in the
# assets-for-api-docs repo:
# https://github.com/flutter/assets-for-api-docs/tree/master/packages/snippets
"$DART" pub global activate snippets 0.4.0
# This script generates a unified doc set, and creates
# a custom index.html, placing everything into DOC_DIR.
# Make sure that create_api_docs.dart has all the dependencies it needs.
(cd "$FLUTTER_ROOT/dev/tools" && "$FLUTTER" pub get)
(cd "$FLUTTER_ROOT" && "$DART" --disable-dart-dev --enable-asserts "$FLUTTER_ROOT/dev/tools/create_api_docs.dart" --output-dir="$DOC_DIR")
}
function main() {
echo "Writing docs build temporary output to $DOC_DIR"
mkdir -p "$DOC_DIR"
generate_docs
# If the destination isn't an absolute path, make it into one.
if ! [[ "$DESTINATION" =~ ^/ ]]; then
DESTINATION="$PWD/$DESTINATION"
fi
# Zip up doc directory and write the output to the destination.
(cd "$OUTPUT_DIR"; zip -r -9 -q "$DESTINATION" ./doc)
if [[ $KEEP_TMP == 1 ]]; then
echo "Temporary document generation output left in $OUTPUT_DIR"
else
echo "Removing Temporary document generation output from $OUTPUT_DIR"
rm -rf "$OUTPUT_DIR"
fi
echo "Wrote docs ZIP file to $DESTINATION"
}
# Zip docs
cd "$FLUTTER_ROOT/dev/docs"
zip -r api_docs.zip doc
parse_args "$@"
main
// Copyright 2014 The Flutter Authors. 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:io';
/// This changes the DocSetPlatformFamily key to be "dartlang" instead of the
/// name of the package (usually "flutter").
///
/// This is so that the IntelliJ plugin for Dash will be able to go directly to
/// the docs for a symbol from a keystroke. Without this, flutter isn't part
/// of the list of package names it searches. After this, it finds the flutter
/// docs because they're declared here to be part of the "dartlang" family of
/// docs.
///
/// Dashing doesn't have a way to configure this, so we modify the Info.plist
/// directly to make the change.
void main(List<String> args) {
final File infoPlist = File('flutter.docset/Contents/Info.plist');
String contents = infoPlist.readAsStringSync();
// Since I didn't want to add the XML package as a dependency just for this,
// I just used a regular expression to make this simple change.
final RegExp findRe = RegExp(r'(\s*<key>DocSetPlatformFamily</key>\s*<string>)[^<]+(</string>)', multiLine: true);
contents = contents.replaceAllMapped(findRe, (Match match) {
return '${match.group(1)}dartlang${match.group(2)}';
});
infoPlist.writeAsStringSync(contents);
}
This diff is collapsed.
This diff is collapsed.
// Copyright 2014 The Flutter Authors. 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:io';
import 'dart:math';
import 'package:archive/archive.dart';
import 'package:http/http.dart' as http;
import 'package:path/path.dart' as path;
const String kDocRoot = 'dev/docs/doc';
/// This script downloads an archive of Javadoc and objc doc for the engine from
/// the artifact store and extracts them to the location used for Dartdoc.
Future<void> main(List<String> args) async {
final String engineVersion = File('bin/internal/engine.version').readAsStringSync().trim();
String engineRealm = File('bin/internal/engine.realm').readAsStringSync().trim();
if (engineRealm.isNotEmpty) {
engineRealm = '$engineRealm/';
}
final String javadocUrl = 'https://storage.googleapis.com/${engineRealm}flutter_infra_release/flutter/$engineVersion/android-javadoc.zip';
generateDocs(javadocUrl, 'javadoc', 'io/flutter/view/FlutterView.html');
final String objcdocUrl = 'https://storage.googleapis.com/${engineRealm}flutter_infra_release/flutter/$engineVersion/ios-objcdoc.zip';
generateDocs(objcdocUrl, 'objcdoc', 'Classes/FlutterViewController.html');
}
/// Fetches the zip archive at the specified url.
///
/// Returns null if the archive fails to download after [maxTries] attempts.
Future<Archive?> fetchArchive(String url, int maxTries) async {
List<int>? responseBytes;
for (int i = 0; i < maxTries; i++) {
final http.Response response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
responseBytes = response.bodyBytes;
break;
}
stderr.writeln('Failed attempt ${i+1} to fetch $url.');
// On failure print a short snipped from the body in case it's helpful.
final int bodyLength = min(1024, response.body.length);
stderr.writeln('Response status code ${response.statusCode}. Body: ${response.body.substring(0, bodyLength)}');
sleep(const Duration(seconds: 1));
}
return responseBytes == null ? null : ZipDecoder().decodeBytes(responseBytes);
}
Future<void> generateDocs(String url, String docName, String checkFile) async {
const int maxTries = 5;
final Archive? archive = await fetchArchive(url, maxTries);
if (archive == null) {
stderr.writeln('Failed to fetch zip archive from: $url after $maxTries attempts. Giving up.');
exit(1);
}
final Directory output = Directory('$kDocRoot/$docName');
print('Extracting $docName to ${output.path}');
output.createSync(recursive: true);
for (final ArchiveFile af in archive) {
if (!af.name.endsWith('/')) {
final File file = File('${output.path}/${af.name}');
file.createSync(recursive: true);
file.writeAsBytesSync(af.content as List<int>);
}
}
/// If object then copy files to old location if the archive is using the new location.
final bool exists = Directory('$kDocRoot/$docName/objectc_docs').existsSync();
if (exists) {
copyFolder(Directory('$kDocRoot/$docName/objectc_docs'), Directory('$kDocRoot/$docName/'));
}
final File testFile = File('${output.path}/$checkFile');
if (!testFile.existsSync()) {
print('Expected file ${testFile.path} not found');
exit(1);
}
print('$docName ready to go!');
}
/// Copies the files in a directory recursively to a new location.
void copyFolder(Directory source, Directory destination) {
source.listSync()
.forEach((FileSystemEntity entity) {
if (entity is Directory) {
final Directory newDirectory = Directory(path.join(destination.absolute.path, path.basename(entity.path)));
newDirectory.createSync();
copyFolder(entity.absolute, newDirectory);
} else if (entity is File) {
entity.copySync(path.join(destination.path, path.basename(entity.path)));
}
});
}
......@@ -12,6 +12,7 @@ dependencies:
meta: 1.9.1
path: 1.8.3
process: 4.2.4
pub_semver: 2.1.4
async: 2.11.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
clock: 1.1.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......@@ -45,7 +46,6 @@ dev_dependencies:
node_preamble: 2.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
package_config: 2.1.0 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pool: 1.5.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
pub_semver: 2.1.4 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf: 1.4.1 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_packages_handler: 3.0.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
shelf_static: 1.1.2 # THIS LINE IS AUTOGENERATED - TO UPDATE USE "flutter update-packages --force-upgrade"
......
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:platform/platform.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:test/test.dart';
import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
import '../create_api_docs.dart' as apidocs;
void main() {
test('getBranchName does not call git if env LUCI_BRANCH provided', () {
final Platform platform = FakePlatform(
environment: <String, String>{
'LUCI_BRANCH': branchName,
},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['flutter', '--version', '--machine'],
stdout: testVersionInfo,
),
],
);
expect(
apidocs.FlutterInformation(platform: platform, processManager: processManager).getBranchName(),
branchName,
);
expect(processManager, hasNoRemainingExpectations);
});
test('getBranchName calls git if env LUCI_BRANCH not provided', () {
final Platform platform = FakePlatform(
environment: <String, String>{},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['flutter', '--version', '--machine'],
stdout: testVersionInfo,
),
const FakeCommand(
command: <String>['git', 'status', '-b', '--porcelain'],
stdout: '## $branchName',
),
],
);
expect(
apidocs.FlutterInformation(platform: platform, processManager: processManager).getBranchName(),
branchName,
);
expect(processManager, hasNoRemainingExpectations);
});
test('getBranchName calls git if env LUCI_BRANCH is empty', () {
final Platform platform = FakePlatform(
environment: <String, String>{
'LUCI_BRANCH': '',
},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['flutter', '--version', '--machine'],
stdout: testVersionInfo,
),
const FakeCommand(
command: <String>['git', 'status', '-b', '--porcelain'],
stdout: '## $branchName',
),
],
);
expect(
apidocs.FlutterInformation(platform: platform, processManager: processManager).getBranchName(),
branchName,
);
expect(processManager, hasNoRemainingExpectations);
});
test("runPubProcess doesn't use the pub binary", () {
final Platform platform = FakePlatform(
environment: <String, String>{
'FLUTTER_ROOT': '/flutter',
},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['/flutter/bin/dart', 'pub', '--one', '--two'],
),
],
);
apidocs.FlutterInformation.instance =
apidocs.FlutterInformation(platform: platform, processManager: processManager);
apidocs.runPubProcess(
arguments: <String>['--one', '--two'],
processManager: processManager,
);
expect(processManager, hasNoRemainingExpectations);
});
group('FlutterInformation', () {
late FakeProcessManager fakeProcessManager;
late FakePlatform fakePlatform;
late MemoryFileSystem memoryFileSystem;
late apidocs.FlutterInformation flutterInformation;
void setUpWithEnvironment(Map<String, String> environment) {
fakePlatform = FakePlatform(environment: environment);
flutterInformation = apidocs.FlutterInformation(
filesystem: memoryFileSystem,
processManager: fakeProcessManager,
platform: fakePlatform,
);
apidocs.FlutterInformation.instance = flutterInformation;
}
setUp(() {
fakeProcessManager = FakeProcessManager.empty();
memoryFileSystem = MemoryFileSystem();
setUpWithEnvironment(<String, String>{});
});
test('calls out to flutter if FLUTTER_VERSION is not set', () async {
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['flutter', '--version', '--machine'], stdout: testVersionInfo));
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['git', 'status', '-b', '--porcelain'], stdout: testVersionInfo));
final Map<String, dynamic> info = flutterInformation.getFlutterInformation();
expect(fakeProcessManager, hasNoRemainingExpectations);
expect(info['frameworkVersion'], equals(Version.parse('2.5.0')));
});
test("doesn't call out to flutter if FLUTTER_VERSION is set", () async {
setUpWithEnvironment(<String, String>{
'FLUTTER_VERSION': testVersionInfo,
});
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['git', 'status', '-b', '--porcelain'], stdout: testVersionInfo));
final Map<String, dynamic> info = flutterInformation.getFlutterInformation();
expect(fakeProcessManager, hasNoRemainingExpectations);
expect(info['frameworkVersion'], equals(Version.parse('2.5.0')));
});
test('getFlutterRoot calls out to flutter if FLUTTER_ROOT is not set', () async {
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['flutter', '--version', '--machine'], stdout: testVersionInfo));
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['git', 'status', '-b', '--porcelain'], stdout: testVersionInfo));
final Directory root = flutterInformation.getFlutterRoot();
expect(fakeProcessManager, hasNoRemainingExpectations);
expect(root.path, equals('/home/user/flutter'));
});
test("getFlutterRoot doesn't call out to flutter if FLUTTER_ROOT is set", () async {
setUpWithEnvironment(<String, String>{'FLUTTER_ROOT': '/home/user/flutter'});
final Directory root = flutterInformation.getFlutterRoot();
expect(fakeProcessManager, hasNoRemainingExpectations);
expect(root.path, equals('/home/user/flutter'));
});
test('parses version properly', () async {
fakePlatform.environment['FLUTTER_VERSION'] = testVersionInfo;
fakeProcessManager.addCommand(
const FakeCommand(command: <Pattern>['git', 'status', '-b', '--porcelain'], stdout: testVersionInfo));
final Map<String, dynamic> info = flutterInformation.getFlutterInformation();
expect(info['frameworkVersion'], isNotNull);
expect(info['frameworkVersion'], equals(Version.parse('2.5.0')));
expect(info['dartSdkVersion'], isNotNull);
expect(info['dartSdkVersion'], equals(Version.parse('2.14.0-360.0.dev')));
});
});
}
const String branchName = 'stable';
const String testVersionInfo = '''
{
"frameworkVersion": "2.5.0",
"channel": "$branchName",
"repositoryUrl": "git@github.com:flutter/flutter.git",
"frameworkRevision": "0000000000000000000000000000000000000000",
"frameworkCommitDate": "2021-07-28 13:03:40 -0700",
"engineRevision": "0000000000000000000000000000000000000001",
"dartSdkVersion": "2.14.0 (build 2.14.0-360.0.dev)",
"flutterRoot": "/home/user/flutter"
}
''';
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:platform/platform.dart';
import 'package:test/test.dart';
import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
import '../dartdoc.dart' show getBranchName, runPubProcess;
void main() {
const String branchName = 'stable';
test('getBranchName does not call git if env LUCI_BRANCH provided', () {
final Platform platform = FakePlatform(
environment: <String, String>{
'LUCI_BRANCH': branchName,
},
);
final ProcessManager processManager = FakeProcessManager.empty();
expect(
getBranchName(
platform: platform,
processManager: processManager,
),
branchName,
);
});
test('getBranchName calls git if env LUCI_BRANCH not provided', () {
final Platform platform = FakePlatform(
environment: <String, String>{},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['git', 'status', '-b', '--porcelain'],
stdout: '## $branchName',
),
],
);
expect(
getBranchName(
platform: platform,
processManager: processManager,
),
branchName,
);
expect(processManager, hasNoRemainingExpectations);
});
test('getBranchName calls git if env LUCI_BRANCH is empty', () {
final Platform platform = FakePlatform(
environment: <String, String>{
'LUCI_BRANCH': '',
},
);
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['git', 'status', '-b', '--porcelain'],
stdout: '## $branchName',
),
],
);
expect(
getBranchName(
platform: platform,
processManager: processManager,
),
branchName,
);
expect(processManager, hasNoRemainingExpectations);
});
test("runPubProcess doesn't use the pub binary", () {
final ProcessManager processManager = FakeProcessManager.list(
<FakeCommand>[
const FakeCommand(
command: <String>['dart', 'pub', '--one', '--two'],
),
],
);
runPubProcess(
dartBinaryPath: 'dart',
arguments: <String>['--one', '--two'],
processManager: processManager,
);
expect(processManager, hasNoRemainingExpectations);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment