Unverified Commit ced3e766 authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Reland: "Reorganize and clarify API doc generator" (#132353) (#132710)

## Description

This re-lands #132353 with some additional options for keeping around the staging directory, so that the recipe for publishing docs can give those options and have the staging directory left around for deploying to the website.

Reverted in #132613

## Related Issues
 - https://flutter-review.googlesource.com/c/recipes/+/49580
parent d19fb632
......@@ -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,115 @@ 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
function usage() {
echo "Usage: $(basename "${BASH_SOURCE[0]}") [--keep-temp] [--output <output.zip>]"
echo ""
echo " --keep-staging Do not delete the staging directory created while generating"
echo " docs. Normally the script deletes the staging directory after"
echo " generating the output ZIP file."
echo " --output <output.zip> specifies where the output ZIP file containing the documentation"
echo " data will be written."
echo " --staging-dir <directory> specifies where the temporary output files will be written while"
echo " generating docs. This directory will be deleted after generation"
echo " unless --keep-staging is also specified."
echo ""
}
function parse_args() {
local arg
local args=()
STAGING_DIR=
KEEP_STAGING=0
DESTINATION="$FLUTTER_ROOT/dev/docs/api_docs.zip"
while (( "$#" )); do
case "$1" in
--help)
usage
exit 0
;;
--staging-dir)
STAGING_DIR="$2"
shift
;;
--keep-staging)
KEEP_STAGING=1
;;
--output)
DESTINATION="$2"
shift
;;
*)
args=("${args[@]}" "$1")
;;
esac
shift
done
if [[ -z $STAGING_DIR ]]; then
STAGING_DIR=$(mktemp -d /tmp/dartdoc.XXXXX)
fi
DOC_DIR="$STAGING_DIR/doc"
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 "$STAGING_DIR"; zip -r -9 -q "$DESTINATION" ./doc)
if [[ $KEEP_STAGING -eq 1 ]]; then
echo "Staging documentation output left in $STAGING_DIR"
else
echo "Removing staging documentation output from $STAGING_DIR"
rm -rf "$STAGING_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;
import '../examples_smoke_test.dart';
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,
filesystem: filesystem,
);
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