Added passing of additional metadata about element to tool, and tests. (#1801)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5e64120..fd38a99 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,6 @@
+## 0.24.1-dev
+* Added more metadata (element name, project name, etc.) to external tool invocations.
+
## 0.24.0
* Add 'override' to feature list for members which override a superclass (#981)
* Support many options via dartdoc_options.yaml (#1674)
diff --git a/lib/src/model.dart b/lib/src/model.dart
index 4ab42ff..7de97cb 100644
--- a/lib/src/model.dart
+++ b/lib/src/model.dart
@@ -3953,7 +3953,21 @@
'Must specify a tool to execute for the @tool directive.');
return '';
}
- return runner.run(args, basicMatch[2]);
+
+ return runner.run(args,
+ content: basicMatch[2],
+ environment: {
+ 'SOURCE_LINE': lineAndColumn?.item1?.toString(),
+ 'SOURCE_COLUMN': lineAndColumn?.item2?.toString(),
+ 'SOURCE_PATH': (sourceFileName == null ||
+ package?.packagePath == null)
+ ? null
+ : pathLib.relative(sourceFileName, from: package.packagePath),
+ 'PACKAGE_PATH': package?.packagePath,
+ 'PACKAGE_NAME': package?.name,
+ 'LIBRARY_NAME': library?.fullyQualifiedName,
+ 'ELEMENT_NAME': fullyQualifiedNameWithoutLibrary,
+ }..removeWhere((key, value) => value == null));
});
} finally {
runner.dispose();
diff --git a/lib/src/tool_runner.dart b/lib/src/tool_runner.dart
index eb457c4..c55ff4a 100644
--- a/lib/src/tool_runner.dart
+++ b/lib/src/tool_runner.dart
@@ -57,10 +57,12 @@
///
/// The [args] must not be null, and it must have at least one member (the name
/// of the tool).
- String run(List<String> args, [String content]) {
+ String run(List<String> args,
+ {String content, Map<String, String> environment}) {
assert(args != null);
assert(args.isNotEmpty);
content ??= '';
+ environment ??= <String, String>{};
var tool = args.removeAt(0);
if (!toolConfiguration.tools.containsKey(tool)) {
_error('Unable to find definition for tool "$tool" in tool map. '
@@ -86,18 +88,28 @@
var tmpFile = _createTemporaryFile();
tmpFile.writeAsStringSync(content);
- // Substitute the temp filename for the "$INPUT" token.
- var fileToken = new RegExp(r'\$INPUT\b');
+ // Substitute the temp filename for the "$INPUT" token, and all of the
+ // other environment variables.
+ // Variables are allowed to either be in $(VAR) form, or $VAR form.
+ var envWithInput = {'INPUT': tmpFile.absolute.path}..addAll(environment);
+ var substitutions = envWithInput.map<RegExp, String>((key, value) {
+ String escapedKey = RegExp.escape(key);
+ return MapEntry(RegExp('\\\$(\\($escapedKey\\)|$escapedKey\\b)'), value);
+ });
var argsWithInput = <String>[];
for (var arg in args) {
- argsWithInput.add(arg.replaceAll(fileToken, tmpFile.absolute.path));
+ var newArg = arg;
+ substitutions
+ .forEach((regex, value) => newArg = newArg.replaceAll(regex, value));
+ argsWithInput.add(newArg);
}
argsWithInput = toolArgs + argsWithInput;
final commandPath = argsWithInput.removeAt(0);
String commandString() => ([commandPath] + argsWithInput).join(' ');
try {
- var result = Process.runSync(commandPath, argsWithInput);
+ var result = Process.runSync(commandPath, argsWithInput,
+ environment: envWithInput);
if (result.exitCode != 0) {
_error('Tool "$tool" returned non-zero exit code '
'(${result.exitCode}) when run as '
diff --git a/lib/src/version.dart b/lib/src/version.dart
index 2d6e6e4..6b610f7 100644
--- a/lib/src/version.dart
+++ b/lib/src/version.dart
@@ -1,2 +1,2 @@
// Generated code. Do not modify.
-const packageVersion = '0.24.0';
+const packageVersion = '0.24.1-dev';
diff --git a/pubspec.yaml b/pubspec.yaml
index 9ddca13..d27e78a 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -1,6 +1,6 @@
name: dartdoc
# Also update the `version` field in lib/dartdoc.dart.
-version: 0.24.0
+version: 0.24.1-dev
author: Dart Team <misc@dartlang.org>
description: A documentation generator for Dart.
homepage: https://github.com/dart-lang/dartdoc
diff --git a/test/model_test.dart b/test/model_test.dart
index 50a8751..91e6940 100644
--- a/test/model_test.dart
+++ b/test/model_test.dart
@@ -83,7 +83,7 @@
Method invokeTool;
Method invokeToolNoInput;
- setUp(() {
+ setUpAll(() {
toolUser = exLibrary.classes.firstWhere((c) => c.name == 'ToolUser');
invokeTool =
toolUser.allInstanceMethods.firstWhere((m) => m.name == 'invokeTool');
@@ -91,22 +91,50 @@
.firstWhere((m) => m.name == 'invokeToolNoInput');
packageGraph.allLocalModelElements.forEach((m) => m.documentation);
});
- test("can invoke a tool", () {
+ test('can invoke a tool and pass args and environment', () {
+ expect(invokeTool.documentation, contains('--file=<INPUT_FILE>'));
expect(
invokeTool.documentation,
contains(
- '''Args: [--file=<INPUT_FILE>, --special= |\\[]!@#\\"\'\$%^&*()_+]'''));
+ new RegExp(r'--source=lib[/\\]example\.dart_[0-9]+_[0-9]+, ')));
+ expect(
+ invokeTool.documentation,
+ contains(new RegExp(
+ r'--package-path=<PACKAGE_PATH>, ')));
+ expect(
+ invokeTool.documentation, contains('--package-name=test_package, '));
+ expect(invokeTool.documentation, contains('--library-name=ex, '));
+ expect(invokeTool.documentation,
+ contains('--element-name=ToolUser.invokeTool, '));
+ expect(invokeTool.documentation,
+ contains(r'''--special= |\[]!@#\"'$%^&*()_+]'''));
+ expect(invokeTool.documentation, contains('INPUT: <INPUT_FILE>'));
+ expect(invokeTool.documentation,
+ contains(new RegExp('SOURCE_LINE: [0-9]+, ')));
+ expect(invokeTool.documentation,
+ contains(new RegExp('SOURCE_COLUMN: [0-9]+, ')));
+ expect(invokeTool.documentation,
+ contains(new RegExp(r'SOURCE_PATH: lib[/\\]example\.dart, ')));
+ expect(
+ invokeTool.documentation,
+ contains(new RegExp(
+ r'PACKAGE_PATH: <PACKAGE_PATH>, ')));
+ expect(
+ invokeTool.documentation, contains('PACKAGE_NAME: test_package, '));
+ expect(invokeTool.documentation, contains('LIBRARY_NAME: ex, '));
+ expect(invokeTool.documentation,
+ contains('ELEMENT_NAME: ToolUser.invokeTool}'));
expect(invokeTool.documentation, contains('## `Yes it is a [Dog]!`'));
});
- test("can invoke a tool and add a reference link", () {
+ test('can invoke a tool and add a reference link', () {
expect(invokeTool.documentation,
contains('Yes it is a [Dog]! Is not a [ToolUser].'));
expect(invokeTool.documentationAsHtml,
- contains(r'<a href="ex/ToolUser-class.html">ToolUser</a>'));
+ contains('<a href="ex/ToolUser-class.html">ToolUser</a>'));
expect(invokeTool.documentationAsHtml,
contains('<a href="ex/Dog-class.html">Dog</a>'));
});
- test(r"can invoke a tool with no $INPUT or args", () {
+ test(r'can invoke a tool with no $INPUT or args', () {
expect(invokeToolNoInput.documentation, contains('Args: []'));
expect(invokeToolNoInput.documentation,
isNot(contains('This text should not appear in the output')));
diff --git a/test/tool_runner_test.dart b/test/tool_runner_test.dart
index 6911103..21a55db 100644
--- a/test/tool_runner_test.dart
+++ b/test/tool_runner_test.dart
@@ -44,16 +44,16 @@
test('can invoke a Dart tool', () {
var result = runner.run(
['drill', r'--file=$INPUT'],
- 'TEST INPUT',
+ content: 'TEST INPUT',
);
expect(errors, isEmpty);
- expect(result, contains(new RegExp(r'Args: \[--file=<INPUT_FILE>]')));
+ expect(result, contains('--file=<INPUT_FILE>'));
expect(result, contains('## `TEST INPUT`'));
});
test('can invoke a non-Dart tool', () {
String result = runner.run(
['non_dart', '--version'],
- 'TEST INPUT',
+ content: 'TEST INPUT',
);
expect(errors, isEmpty);
expect(result, isEmpty); // Output is on stderr.
@@ -61,7 +61,7 @@
test('fails if tool not in tool map', () {
String result = runner.run(
['hammer', r'--file=$INPUT'],
- 'TEST INPUT',
+ content: 'TEST INPUT',
);
expect(errors, isNotEmpty);
expect(
@@ -71,7 +71,7 @@
test('fails if tool returns non-zero status', () {
String result = runner.run(
['drill', r'--file=/a/missing/file'],
- 'TEST INPUT',
+ content: 'TEST INPUT',
);
expect(errors, isNotEmpty);
expect(errors[0], contains('Tool "drill" returned non-zero exit code'));
@@ -80,7 +80,7 @@
test("fails if tool in tool map doesn't exist", () {
String result = runner.run(
['missing'],
- 'TEST INPUT',
+ content: 'TEST INPUT',
);
expect(errors, isNotEmpty);
expect(errors[0],
diff --git a/testing/test_package/bin/drill.dart b/testing/test_package/bin/drill.dart
index 76d616b..9978971 100644
--- a/testing/test_package/bin/drill.dart
+++ b/testing/test_package/bin/drill.dart
@@ -14,16 +14,43 @@
final ArgParser argParser = ArgParser();
argParser.addOption('file');
argParser.addOption('special');
+ argParser.addOption('source');
+ argParser.addOption('package-name');
+ argParser.addOption('package-path');
+ argParser.addOption('library-name');
+ argParser.addOption('element-name');
final ArgResults args = argParser.parse(argList);
+ // Normalize the filenames, since they include random
+ // and system-specific components, but make sure they
+ // match the patterns we expect.
+ RegExp inputFileRegExp = new RegExp(
+ r'(--file=)?(.*)([/\\]dartdoc_tools_)([^/\\]+)([/\\]input_)(\d+)');
+ RegExp packagePathRegExp =
+ new RegExp(r'(--package-path=)?(.+dartdoc.*[/\\]testing[/\\]test_package)');
- // Normalize the filename, since it includes random
- // and system-specific components, but make sure it
- // matches the pattern we expect.
- RegExp filenameRegExp = new RegExp(
- r'(--file=)(.*)([/\\]dartdoc_tools_)([^/\\]+)([/\\]input_)(\d+)');
+ final Set<String> variableNames = new Set<String>.from([
+ 'INPUT',
+ 'SOURCE_LINE',
+ 'SOURCE_COLUMN',
+ 'SOURCE_PATH',
+ 'PACKAGE_NAME',
+ 'PACKAGE_PATH',
+ 'LIBRARY_NAME',
+ 'ELEMENT_NAME'
+ ]);
+ Map<String, String> env = <String, String>{}..addAll(Platform.environment);
+ env.removeWhere((String key, String value) => !variableNames.contains(key));
+ env.updateAll(
+ (key, value) => inputFileRegExp.hasMatch(value) ? '<INPUT_FILE>' : value);
+ env.updateAll((key, value) =>
+ packagePathRegExp.hasMatch(value) ? '<PACKAGE_PATH>' : value);
+ print('Env: ${env}');
+
List<String> normalized = argList.map((String arg) {
- if (filenameRegExp.hasMatch(arg)) {
+ if (inputFileRegExp.hasMatch(arg)) {
return '--file=<INPUT_FILE>';
+ } else if (packagePathRegExp.hasMatch(arg)) {
+ return '--package-path=<PACKAGE_PATH>';
} else {
return arg;
}
diff --git a/testing/test_package/lib/example.dart b/testing/test_package/lib/example.dart
index b6388fe..d0ef5fc 100644
--- a/testing/test_package/lib/example.dart
+++ b/testing/test_package/lib/example.dart
@@ -585,7 +585,7 @@
abstract class ToolUser {
/// Invokes a tool.
///
- /// {@tool drill --file="$INPUT" --special=" |\[]!@#\"'$%^&*()_+"}
+ /// {@tool drill --file="$INPUT" --source="$(SOURCE_PATH)_$(SOURCE_LINE)_$SOURCE_COLUMN" --package-path=$PACKAGE_PATH --package-name=$PACKAGE_NAME --library-name=$LIBRARY_NAME --element-name=$(ELEMENT_NAME) --special=" |\[]!@#\"'$%^&*()_+"}
/// Yes it is a [Dog]!
/// Ok, fine it isn't.
/// {@end-tool}
diff --git a/testing/test_package_docs/__404error.html b/testing/test_package_docs/__404error.html
index 886ad00..c03252a 100644
--- a/testing/test_package_docs/__404error.html
+++ b/testing/test_package_docs/__404error.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="generator" content="made with love by dartdoc 0.24.0">
+ <meta name="generator" content="made with love by dartdoc 0.24.1-dev">
<meta name="description" content="test_package API docs, for the Dart programming language.">
<title>test_package - Dart API docs</title>
diff --git a/testing/test_package_docs/ex/ToolUser/invokeTool.html b/testing/test_package_docs/ex/ToolUser/invokeTool.html
index 6b60d5c..950d069 100644
--- a/testing/test_package_docs/ex/ToolUser/invokeTool.html
+++ b/testing/test_package_docs/ex/ToolUser/invokeTool.html
@@ -73,7 +73,8 @@
</section>
<section class="desc markdown">
<p>Invokes a tool.</p>
-<p>Args: <code>--file=<INPUT_FILE>, --special= |[</code>!@#"'$%^&*()_+]</p>
+<p>Env: {INPUT: <INPUT_FILE>, SOURCE_LINE: 592, SOURCE_COLUMN: 8, SOURCE_PATH: lib/example.dart, PACKAGE_PATH: <PACKAGE_PATH>, PACKAGE_NAME: test_package, LIBRARY_NAME: ex, ELEMENT_NAME: ToolUser.invokeTool}
+Args: <code>--file=<INPUT_FILE>, --source=lib/example.dart_592_8, --package-path=<PACKAGE_PATH>, --package-name=test_package, --library-name=ex, --element-name=ToolUser.invokeTool, --special= |[</code>!@#"'$%^&*()_+]</p>
<h2 id="yes-it-is-a-dog"><code>Yes it is a [Dog]!</code></h2>
<p>Yes it is a <a href="ex/Dog-class.html">Dog</a>! Is not a <a href="ex/ToolUser-class.html">ToolUser</a>.</p>
<h2 id="ok-fine-it-isnt"><code>Ok, fine it isn't.</code></h2>
diff --git a/testing/test_package_docs/ex/ToolUser/invokeToolNoInput.html b/testing/test_package_docs/ex/ToolUser/invokeToolNoInput.html
index 10a727e..6b0e0e1 100644
--- a/testing/test_package_docs/ex/ToolUser/invokeToolNoInput.html
+++ b/testing/test_package_docs/ex/ToolUser/invokeToolNoInput.html
@@ -73,7 +73,8 @@
</section>
<section class="desc markdown">
<p>Invokes a tool without the $INPUT token or args.</p>
-<p>Args: []</p>
+<p>Env: {INPUT: <INPUT_FILE>, SOURCE_LINE: 599, SOURCE_COLUMN: 8, SOURCE_PATH: lib/example.dart, PACKAGE_PATH: <PACKAGE_PATH>, PACKAGE_NAME: test_package, LIBRARY_NAME: ex, ELEMENT_NAME: ToolUser.invokeToolNoInput}
+Args: []</p>
</section>
diff --git a/testing/test_package_docs/index.html b/testing/test_package_docs/index.html
index b7564b3..25d97f5 100644
--- a/testing/test_package_docs/index.html
+++ b/testing/test_package_docs/index.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="generator" content="made with love by dartdoc 0.24.0">
+ <meta name="generator" content="made with love by dartdoc 0.24.1-dev">
<meta name="description" content="test_package API docs, for the Dart programming language.">
<title>test_package - Dart API docs</title>
diff --git a/testing/test_package_docs_dev/__404error.html b/testing/test_package_docs_dev/__404error.html
index 886ad00..c03252a 100644
--- a/testing/test_package_docs_dev/__404error.html
+++ b/testing/test_package_docs_dev/__404error.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="generator" content="made with love by dartdoc 0.24.0">
+ <meta name="generator" content="made with love by dartdoc 0.24.1-dev">
<meta name="description" content="test_package API docs, for the Dart programming language.">
<title>test_package - Dart API docs</title>
diff --git a/testing/test_package_docs_dev/ex/ToolUser/invokeTool.html b/testing/test_package_docs_dev/ex/ToolUser/invokeTool.html
index 6b60d5c..950d069 100644
--- a/testing/test_package_docs_dev/ex/ToolUser/invokeTool.html
+++ b/testing/test_package_docs_dev/ex/ToolUser/invokeTool.html
@@ -73,7 +73,8 @@
</section>
<section class="desc markdown">
<p>Invokes a tool.</p>
-<p>Args: <code>--file=<INPUT_FILE>, --special= |[</code>!@#"'$%^&*()_+]</p>
+<p>Env: {INPUT: <INPUT_FILE>, SOURCE_LINE: 592, SOURCE_COLUMN: 8, SOURCE_PATH: lib/example.dart, PACKAGE_PATH: <PACKAGE_PATH>, PACKAGE_NAME: test_package, LIBRARY_NAME: ex, ELEMENT_NAME: ToolUser.invokeTool}
+Args: <code>--file=<INPUT_FILE>, --source=lib/example.dart_592_8, --package-path=<PACKAGE_PATH>, --package-name=test_package, --library-name=ex, --element-name=ToolUser.invokeTool, --special= |[</code>!@#"'$%^&*()_+]</p>
<h2 id="yes-it-is-a-dog"><code>Yes it is a [Dog]!</code></h2>
<p>Yes it is a <a href="ex/Dog-class.html">Dog</a>! Is not a <a href="ex/ToolUser-class.html">ToolUser</a>.</p>
<h2 id="ok-fine-it-isnt"><code>Ok, fine it isn't.</code></h2>
diff --git a/testing/test_package_docs_dev/ex/ToolUser/invokeToolNoInput.html b/testing/test_package_docs_dev/ex/ToolUser/invokeToolNoInput.html
index 10a727e..6b0e0e1 100644
--- a/testing/test_package_docs_dev/ex/ToolUser/invokeToolNoInput.html
+++ b/testing/test_package_docs_dev/ex/ToolUser/invokeToolNoInput.html
@@ -73,7 +73,8 @@
</section>
<section class="desc markdown">
<p>Invokes a tool without the $INPUT token or args.</p>
-<p>Args: []</p>
+<p>Env: {INPUT: <INPUT_FILE>, SOURCE_LINE: 599, SOURCE_COLUMN: 8, SOURCE_PATH: lib/example.dart, PACKAGE_PATH: <PACKAGE_PATH>, PACKAGE_NAME: test_package, LIBRARY_NAME: ex, ELEMENT_NAME: ToolUser.invokeToolNoInput}
+Args: []</p>
</section>
diff --git a/testing/test_package_docs_dev/index.html b/testing/test_package_docs_dev/index.html
index b7564b3..25d97f5 100644
--- a/testing/test_package_docs_dev/index.html
+++ b/testing/test_package_docs_dev/index.html
@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
- <meta name="generator" content="made with love by dartdoc 0.24.0">
+ <meta name="generator" content="made with love by dartdoc 0.24.1-dev">
<meta name="description" content="test_package API docs, for the Dart programming language.">
<title>test_package - Dart API docs</title>