mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:31:50 +00:00
Initial and intentionally minimal pkg/dartdev/ package. This includes some initial CLI utilities and test file.
Change-Id: I2b8485a1918fb0f1b6c5f0cbe626418aeef9c06e Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/132025 Commit-Queue: Jaime Wren <jwren@google.com> Reviewed-by: Devon Carew <devoncarew@google.com>
This commit is contained in:
parent
1bd047a67a
commit
4da1bb0da7
|
@ -33,6 +33,7 @@ dart2js_tools:pkg/dart2js_tools/lib
|
||||||
dart2native:pkg/dart2native/lib
|
dart2native:pkg/dart2native/lib
|
||||||
dart_internal:pkg/dart_internal/lib
|
dart_internal:pkg/dart_internal/lib
|
||||||
dart_style:third_party/pkg_tested/dart_style/lib
|
dart_style:third_party/pkg_tested/dart_style/lib
|
||||||
|
dartdev:pkg/dartdev/lib
|
||||||
dartdoc:third_party/pkg/dartdoc/lib
|
dartdoc:third_party/pkg/dartdoc/lib
|
||||||
dartfix:pkg/dartfix/lib
|
dartfix:pkg/dartfix/lib
|
||||||
dev_compiler:pkg/dev_compiler/lib
|
dev_compiler:pkg/dev_compiler/lib
|
||||||
|
|
10
pkg/dartdev/.gitignore
vendored
Normal file
10
pkg/dartdev/.gitignore
vendored
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
.buildlog
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
.project
|
||||||
|
.settings/
|
||||||
|
build/
|
||||||
|
pubspec.lock
|
||||||
|
|
||||||
|
# Directory created by dartdoc
|
||||||
|
doc/api/
|
2
pkg/dartdev/CHANGELOG.md
Normal file
2
pkg/dartdev/CHANGELOG.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
## 0.0.1
|
||||||
|
* Initial commit adding `pkg/dartdev/` to the Dart SDK with initial package files
|
26
pkg/dartdev/LICENSE
Normal file
26
pkg/dartdev/LICENSE
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
Copyright 2020, the Dart project authors. All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are
|
||||||
|
met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided
|
||||||
|
with the distribution.
|
||||||
|
* Neither the name of Google Inc. nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
7
pkg/dartdev/README.md
Normal file
7
pkg/dartdev/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# dartdev
|
||||||
|
|
||||||
|
A command-line utility for Dart development.
|
||||||
|
|
||||||
|
## Docs
|
||||||
|
|
||||||
|
This tool is currently under active development.
|
1
pkg/dartdev/analysis_options.yaml
Normal file
1
pkg/dartdev/analysis_options.yaml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include: package:pedantic/analysis_options.1.8.0.yaml
|
25
pkg/dartdev/bin/dartdev.dart
Normal file
25
pkg/dartdev/bin/dartdev.dart
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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:io';
|
||||||
|
|
||||||
|
import 'package:args/command_runner.dart';
|
||||||
|
import 'package:dartdev/dartdev.dart';
|
||||||
|
|
||||||
|
/// The entry point for dartdev.
|
||||||
|
main(List<String> args) async {
|
||||||
|
final runner = DartdevRunner();
|
||||||
|
try {
|
||||||
|
dynamic result = await runner.run(args);
|
||||||
|
exit(result is int ? result : 0);
|
||||||
|
} catch (e) {
|
||||||
|
if (e is UsageException) {
|
||||||
|
stderr.writeln('$e');
|
||||||
|
exit(64);
|
||||||
|
} else {
|
||||||
|
stderr.writeln('$e');
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
32
pkg/dartdev/lib/dartdev.dart
Normal file
32
pkg/dartdev/lib/dartdev.dart
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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 'package:args/args.dart';
|
||||||
|
import 'package:args/command_runner.dart';
|
||||||
|
import 'package:cli_util/cli_logging.dart';
|
||||||
|
|
||||||
|
import 'src/commands/format.dart';
|
||||||
|
import 'src/core.dart';
|
||||||
|
|
||||||
|
class DartdevRunner extends CommandRunner {
|
||||||
|
static const String dartdevDescription =
|
||||||
|
'A command-line utility for Dart development';
|
||||||
|
|
||||||
|
DartdevRunner() : super('dartdev', '$dartdevDescription.') {
|
||||||
|
argParser.addFlag('verbose',
|
||||||
|
abbr: 'v', negatable: false, help: 'Show verbose output.');
|
||||||
|
|
||||||
|
// The list of currently supported commands:
|
||||||
|
addCommand(FormatCommand());
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future runCommand(ArgResults results) async {
|
||||||
|
isVerbose = results['verbose'];
|
||||||
|
|
||||||
|
log = isVerbose ? Logger.verbose(ansi: ansi) : Logger.standard(ansi: ansi);
|
||||||
|
|
||||||
|
return await super.runCommand(results);
|
||||||
|
}
|
||||||
|
}
|
24
pkg/dartdev/lib/src/commands/format.dart
Normal file
24
pkg/dartdev/lib/src/commands/format.dart
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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 '../core.dart';
|
||||||
|
import '../sdk.dart';
|
||||||
|
|
||||||
|
class FormatCommand extends DartdevCommand {
|
||||||
|
FormatCommand() : super('format', 'Format one or more Dart files.') {
|
||||||
|
// TODO(jwren) add all options and flags
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
run() async {
|
||||||
|
// TODO(jwren) implement verbose in dart_style
|
||||||
|
// dartfmt doesn't have '-v' or '--verbose', so remove from the argument list
|
||||||
|
var args = List.from(argResults.arguments)
|
||||||
|
..remove('-v')
|
||||||
|
..remove('--verbose');
|
||||||
|
var process = await startProcess(sdk.dartfmt, args);
|
||||||
|
routeToStdout(process);
|
||||||
|
return process.exitCode;
|
||||||
|
}
|
||||||
|
}
|
82
pkg/dartdev/lib/src/core.dart
Normal file
82
pkg/dartdev/lib/src/core.dart
Normal file
|
@ -0,0 +1,82 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:args/command_runner.dart';
|
||||||
|
import 'package:cli_util/cli_logging.dart';
|
||||||
|
|
||||||
|
Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
|
||||||
|
Logger log;
|
||||||
|
bool isVerbose = false;
|
||||||
|
|
||||||
|
abstract class DartdevCommand extends Command {
|
||||||
|
final String _name;
|
||||||
|
final String _description;
|
||||||
|
|
||||||
|
DartdevCommand(this._name, this._description);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get name => _name;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get description => _description;
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Process> startProcess(
|
||||||
|
String executable,
|
||||||
|
List<String> arguments, {
|
||||||
|
String cwd,
|
||||||
|
}) {
|
||||||
|
log.trace('$executable ${arguments.join(' ')}');
|
||||||
|
return Process.start(executable, arguments, workingDirectory: cwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void routeToStdout(
|
||||||
|
Process process, {
|
||||||
|
bool logToTrace = false,
|
||||||
|
void listener(String str),
|
||||||
|
}) {
|
||||||
|
if (isVerbose) {
|
||||||
|
_streamLineTransform(process.stdout, (String line) {
|
||||||
|
logToTrace ? log.trace(line.trimRight()) : log.stdout(line.trimRight());
|
||||||
|
if (listener != null) listener(line);
|
||||||
|
});
|
||||||
|
_streamLineTransform(process.stderr, (String line) {
|
||||||
|
log.stderr(line.trimRight());
|
||||||
|
if (listener != null) listener(line);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
_streamLineTransform(process.stdout, (String line) {
|
||||||
|
logToTrace ? log.trace(line.trimRight()) : log.stdout(line.trimRight());
|
||||||
|
if (listener != null) listener(line);
|
||||||
|
});
|
||||||
|
|
||||||
|
_streamLineTransform(process.stderr, (String line) {
|
||||||
|
log.stderr(line.trimRight());
|
||||||
|
if (listener != null) listener(line);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void routeToStdoutStreaming(Process process) {
|
||||||
|
if (isVerbose) {
|
||||||
|
_streamLineTransform(
|
||||||
|
process.stdout, (line) => log.stdout(line.trimRight()));
|
||||||
|
_streamLineTransform(
|
||||||
|
process.stderr, (line) => log.stderr(line.trimRight()));
|
||||||
|
} else {
|
||||||
|
process.stdout.listen((List<int> data) => stdout.add(data));
|
||||||
|
_streamLineTransform(
|
||||||
|
process.stderr, (line) => log.stderr(line.trimRight()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _streamLineTransform(Stream<List<int>> stream, handler(String line)) {
|
||||||
|
stream
|
||||||
|
.transform(utf8.decoder)
|
||||||
|
.transform(const LineSplitter())
|
||||||
|
.listen(handler);
|
||||||
|
}
|
31
pkg/dartdev/lib/src/sdk.dart
Normal file
31
pkg/dartdev/lib/src/sdk.dart
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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:io';
|
||||||
|
|
||||||
|
import 'package:cli_util/cli_util.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
final Sdk sdk = Sdk();
|
||||||
|
|
||||||
|
/// A utility class for finding and referencing paths within the Dart SDK.
|
||||||
|
class Sdk {
|
||||||
|
final String dir;
|
||||||
|
|
||||||
|
Sdk() : dir = getSdkPath();
|
||||||
|
|
||||||
|
String get dart => path.join(dir, 'bin', _exeName('dart'));
|
||||||
|
|
||||||
|
String get dartanalyzer => path.join(dir, 'bin', _binName('dartanalyzer'));
|
||||||
|
|
||||||
|
String get dartfmt => path.join(dir, 'bin', _binName('dartfmt'));
|
||||||
|
|
||||||
|
String get pub => path.join(dir, 'bin', _binName('pub'));
|
||||||
|
|
||||||
|
static String _binName(String base) =>
|
||||||
|
Platform.isWindows ? '$base.bat' : base;
|
||||||
|
|
||||||
|
static String _exeName(String base) =>
|
||||||
|
Platform.isWindows ? '$base.exe' : base;
|
||||||
|
}
|
32
pkg/dartdev/lib/src/utils.dart
Normal file
32
pkg/dartdev/lib/src/utils.dart
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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:io';
|
||||||
|
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
/// The directory used to store per-user settings for Dart tooling.
|
||||||
|
Directory getDartPrefsDirectory() {
|
||||||
|
return Directory(path.join(getUserHomeDir(), '.dart'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the user's home directory.
|
||||||
|
String getUserHomeDir() {
|
||||||
|
String envKey = Platform.operatingSystem == 'windows' ? 'APPDATA' : 'HOME';
|
||||||
|
String value = Platform.environment[envKey];
|
||||||
|
return value == null ? '.' : value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A typedef to represent a function taking no arguments and with no return
|
||||||
|
/// value.
|
||||||
|
typedef void VoidFunction();
|
||||||
|
|
||||||
|
final NumberFormat _numberFormat = NumberFormat.decimalPattern();
|
||||||
|
|
||||||
|
/// Convert the given number to a string using the current locale.
|
||||||
|
String formatNumber(int i) => _numberFormat.format(i);
|
||||||
|
|
||||||
|
/// Emit the given word with the correct pluralization.
|
||||||
|
String pluralize(String word, int count) => count == 1 ? word : '${word}s';
|
18
pkg/dartdev/pubspec.yaml
Normal file
18
pkg/dartdev/pubspec.yaml
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
name: dartdev
|
||||||
|
|
||||||
|
# This package is not intended to be published
|
||||||
|
publish_to: none
|
||||||
|
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.6.0 <3.0.0'
|
||||||
|
dependencies:
|
||||||
|
args: ^1.5.2
|
||||||
|
cli_util: ^0.1.0
|
||||||
|
intl: ^0.16.0
|
||||||
|
path: ^1.6.2
|
||||||
|
watcher: ^0.9.7+13
|
||||||
|
yaml: ^2.2.0
|
||||||
|
|
||||||
|
dev_dependencies:
|
||||||
|
test: ^1.0.0
|
||||||
|
pedantic: ^1.8.0
|
66
pkg/dartdev/test/command_test.dart
Normal file
66
pkg/dartdev/test/command_test.dart
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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:io';
|
||||||
|
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
// TODO(jwren) move the following test utilities to a separate file
|
||||||
|
|
||||||
|
// Files that end in _test.dart must have a main method to satisfy the dart2js
|
||||||
|
// bots
|
||||||
|
void main() {
|
||||||
|
test('empty test for dart2js', () {
|
||||||
|
assert(true == true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
TestProject project({String mainSrc}) => TestProject(mainSrc: mainSrc);
|
||||||
|
|
||||||
|
class TestProject {
|
||||||
|
Directory dir;
|
||||||
|
|
||||||
|
static String get defaultProjectName => 'dartdev_temp';
|
||||||
|
|
||||||
|
String get name => defaultProjectName;
|
||||||
|
|
||||||
|
TestProject({String mainSrc}) {
|
||||||
|
dir = Directory.systemTemp.createTempSync('dartdev');
|
||||||
|
if (mainSrc != null) {
|
||||||
|
file('lib/main.dart', mainSrc);
|
||||||
|
}
|
||||||
|
file('pubspec.yaml', 'name: $name\ndev_dependencies:\n test: any\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void file(String name, String contents) {
|
||||||
|
var file = File(path.join(dir.path, name));
|
||||||
|
file.parent.createSync();
|
||||||
|
file.writeAsStringSync(contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
void dispose() {
|
||||||
|
dir.deleteSync(recursive: true);
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessResult run(String command, [List<String> args]) {
|
||||||
|
var arguments = [
|
||||||
|
path.absolute(path.join(Directory.current.path, 'bin', 'dartdev.dart')),
|
||||||
|
command
|
||||||
|
];
|
||||||
|
if (args != null && args.isNotEmpty) {
|
||||||
|
arguments.addAll(args);
|
||||||
|
}
|
||||||
|
return Process.runSync(
|
||||||
|
Platform.resolvedExecutable,
|
||||||
|
arguments,
|
||||||
|
workingDirectory: dir.path,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
File findFile(String name) {
|
||||||
|
var file = File(path.join(dir.path, name));
|
||||||
|
return file.existsSync() ? file : null;
|
||||||
|
}
|
||||||
|
}
|
22
pkg/dartdev/test/utils_test.dart
Normal file
22
pkg/dartdev/test/utils_test.dart
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// 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 'package:dartdev/src/utils.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('pluralize', () {
|
||||||
|
test('zero', () {
|
||||||
|
expect(pluralize('cat', 0), 'cats');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('one', () {
|
||||||
|
expect(pluralize('cat', 1), 'cat');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('many', () {
|
||||||
|
expect(pluralize('cat', 2), 'cats');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
|
@ -2403,6 +2403,11 @@
|
||||||
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
|
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
|
||||||
"arguments": ["--fatal-warnings", "pkg/compiler"]
|
"arguments": ["--fatal-warnings", "pkg/compiler"]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "analyze pkg/dartdev",
|
||||||
|
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
|
||||||
|
"arguments": ["--fatal-warnings", "pkg/dartdev"]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "analyze pkg/dart2js_tools",
|
"name": "analyze pkg/dart2js_tools",
|
||||||
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
|
"script": "out/ReleaseX64/dart-sdk/bin/dartanalyzer",
|
||||||
|
|
Loading…
Reference in a new issue