Skip to content

Commit b51098c

Browse files
committed
Move ToolDefinition and related classes out of dartdoc_options
1 parent 99f45ab commit b51098c

File tree

5 files changed

+261
-230
lines changed

5 files changed

+261
-230
lines changed

lib/dartdoc.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import 'package:dartdoc/src/logging.dart';
2323
import 'package:dartdoc/src/markdown_processor.dart' show markdownStats;
2424
import 'package:dartdoc/src/model/model.dart';
2525
import 'package:dartdoc/src/package_meta.dart';
26+
import 'package:dartdoc/src/tool_definition.dart';
2627
import 'package:dartdoc/src/tool_runner.dart';
2728
import 'package:dartdoc/src/tuple.dart';
2829
import 'package:dartdoc/src/utils.dart';

lib/src/dartdoc_options.dart

Lines changed: 7 additions & 220 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ import 'package:dartdoc/dartdoc.dart';
2424
import 'package:dartdoc/src/experiment_options.dart';
2525
import 'package:dartdoc/src/io_utils.dart';
2626
import 'package:dartdoc/src/source_linker.dart';
27+
import 'package:dartdoc/src/tool_definition.dart';
2728
import 'package:dartdoc/src/tool_runner.dart';
28-
import 'package:dartdoc/src/tuple.dart';
2929
import 'package:dartdoc/src/warnings.dart';
30-
import 'package:path/path.dart' as p show Context, canonicalize, extension;
30+
import 'package:path/path.dart' as p show Context, canonicalize;
3131
import 'package:yaml/yaml.dart';
3232

3333
/// Constants to help with type checking, because T is int and so forth
@@ -39,7 +39,7 @@ const int _kIntVal = 0;
3939
const double _kDoubleVal = 0.0;
4040
const bool _kBoolVal = true;
4141

42-
const String _kCompileArgsTagName = 'compile_args';
42+
const String compileArgsTagName = 'compile_args';
4343

4444
int get _usageLineLength => stdout.hasTerminal ? stdout.terminalColumns : null;
4545

@@ -114,219 +114,6 @@ class CategoryConfiguration {
114114
}
115115
}
116116

117-
/// Defines the attributes of a tool in the options file, corresponding to
118-
/// the 'tools' keyword in the options file, and populated by the
119-
/// [ToolConfiguration] class.
120-
class ToolDefinition {
121-
/// A list containing the command and options to be run for this tool. The
122-
/// first argument in the command is the tool executable, and will have its
123-
/// path evaluated relative to the `dartdoc_options.yaml` location. Must not
124-
/// be an empty list, or be null.
125-
final List<String> command;
126-
127-
/// A list containing the command and options to setup phase for this tool.
128-
/// The first argument in the command is the tool executable, and will have
129-
/// its path evaluated relative to the `dartdoc_options.yaml` location. May
130-
/// be null or empty, in which case it will be ignored at setup time.
131-
final List<String> setupCommand;
132-
133-
/// A description of the defined tool. Must not be null.
134-
final String description;
135-
136-
/// If set, then the setup command has been run once for this tool definition.
137-
bool setupComplete = false;
138-
139-
/// Returns true if the given executable path has an extension recognized as a
140-
/// Dart extension (e.g. '.dart' or '.snapshot').
141-
static bool isDartExecutable(String executable) {
142-
var extension = p.extension(executable);
143-
return extension == '.dart' || extension == '.snapshot';
144-
}
145-
146-
/// Creates a ToolDefinition or subclass that is appropriate for the command
147-
/// given.
148-
factory ToolDefinition.fromCommand(
149-
List<String> command,
150-
List<String> setupCommand,
151-
String description,
152-
ResourceProvider resourceProvider,
153-
{List<String> compileArgs}) {
154-
assert(command != null);
155-
assert(command.isNotEmpty);
156-
assert(description != null);
157-
if (isDartExecutable(command[0])) {
158-
return DartToolDefinition(
159-
command, setupCommand, description, resourceProvider,
160-
compileArgs: compileArgs ?? const []);
161-
} else {
162-
if (compileArgs != null && compileArgs.isNotEmpty) {
163-
throw DartdocOptionError(
164-
'Compile arguments may only be specified for Dart tools, but '
165-
'$_kCompileArgsTagName of $compileArgs were specified for '
166-
'$command.');
167-
}
168-
return ToolDefinition(command, setupCommand, description);
169-
}
170-
}
171-
172-
ToolDefinition(this.command, this.setupCommand, this.description)
173-
: assert(command != null),
174-
assert(command.isNotEmpty),
175-
assert(description != null);
176-
177-
@override
178-
String toString() {
179-
final commandString =
180-
'${this is DartToolDefinition ? '(Dart) ' : ''}"${command.join(' ')}"';
181-
if (setupCommand == null) {
182-
return '$runtimeType: $commandString ($description)';
183-
} else {
184-
return '$runtimeType: $commandString, with setup command '
185-
'"${setupCommand.join(' ')}" ($description)';
186-
}
187-
}
188-
}
189-
190-
/// Manages the creation of a single snapshot file in a context where multiple
191-
/// async functions could be trying to use and/or create it.
192-
///
193-
/// To use:
194-
///
195-
/// var s = new Snapshot(...);
196-
///
197-
/// if (s.needsSnapshot) {
198-
/// // create s.snapshotFile, then call:
199-
/// s.snapshotCompleted();
200-
/// } else {
201-
/// await snapshotValid();
202-
/// // use existing s.snapshotFile;
203-
/// }
204-
///
205-
class Snapshot {
206-
File _snapshotFile;
207-
208-
// TODO(srawlins): Deprecate this public getter; change private field to just
209-
// be the absolute path.
210-
File get snapshotFile => _snapshotFile;
211-
final Completer<void> _snapshotCompleter = Completer();
212-
213-
Snapshot(Folder snapshotCache, String toolPath, int serial,
214-
ResourceProvider resourceProvider) {
215-
if (toolPath.endsWith('.snapshot')) {
216-
_needsSnapshot = false;
217-
_snapshotFile = resourceProvider.getFile(toolPath);
218-
snapshotCompleted();
219-
} else {
220-
_snapshotFile = resourceProvider.getFile(resourceProvider.pathContext
221-
.join(resourceProvider.pathContext.absolute(snapshotCache.path),
222-
'snapshot_$serial'));
223-
}
224-
}
225-
226-
bool _needsSnapshot = true;
227-
228-
/// Will return true precisely once, unless [snapshotFile] was already a
229-
/// snapshot. In that case, will always return false.
230-
bool get needsSnapshot {
231-
if (_needsSnapshot == true) {
232-
_needsSnapshot = false;
233-
return true;
234-
}
235-
return _needsSnapshot;
236-
}
237-
238-
Future<void> snapshotValid() => _snapshotCompleter.future;
239-
240-
void snapshotCompleted() => _snapshotCompleter.complete();
241-
}
242-
243-
/// A singleton that keeps track of cached snapshot files. The [dispose]
244-
/// function must be called before process exit to clean up snapshots in the
245-
/// cache.
246-
class SnapshotCache {
247-
static SnapshotCache _instance;
248-
249-
// TODO(srawlins): Make this final.
250-
Folder snapshotCache;
251-
final ResourceProvider _resourceProvider;
252-
final Map<String, Snapshot> snapshots = {};
253-
int _serial = 0;
254-
255-
SnapshotCache._(this._resourceProvider)
256-
: snapshotCache =
257-
_resourceProvider.createSystemTemp('dartdoc_snapshot_cache_');
258-
259-
static SnapshotCache get instance => _instance;
260-
261-
static SnapshotCache createInstance(ResourceProvider resourceProvider) =>
262-
_instance ??= SnapshotCache._(resourceProvider);
263-
264-
Snapshot getSnapshot(String toolPath) {
265-
if (snapshots.containsKey(toolPath)) {
266-
return snapshots[toolPath];
267-
}
268-
snapshots[toolPath] =
269-
Snapshot(snapshotCache, toolPath, _serial, _resourceProvider);
270-
_serial++;
271-
return snapshots[toolPath];
272-
}
273-
274-
void dispose() {
275-
_instance = null;
276-
if (snapshotCache != null && snapshotCache.exists) {
277-
return snapshotCache.delete();
278-
}
279-
return null;
280-
}
281-
}
282-
283-
/// A special kind of tool definition for Dart commands.
284-
class DartToolDefinition extends ToolDefinition {
285-
final ResourceProvider _resourceProvider;
286-
287-
/// A list of arguments to add to the snapshot compilation arguments.
288-
final List<String> compileArgs;
289-
290-
/// Takes a list of args to modify, and returns the name of the executable
291-
/// to run. If no snapshot file existed, then create one and modify the args
292-
/// so that if they are executed with dart, will result in the snapshot being
293-
/// built.
294-
Future<Tuple2<String, Function()>> modifyArgsToCreateSnapshotIfNeeded(
295-
List<String> args) async {
296-
assert(args[0] == command.first);
297-
// Set up flags to create a new snapshot, if needed, and use the first run
298-
// as the training run.
299-
SnapshotCache.createInstance(_resourceProvider);
300-
var snapshot = SnapshotCache.instance.getSnapshot(command.first);
301-
var snapshotFile = snapshot.snapshotFile;
302-
var needsSnapshot = snapshot.needsSnapshot;
303-
if (needsSnapshot) {
304-
args.insertAll(0, [
305-
// TODO(jcollins-g): remove ignore and verbosity resets once
306-
// https://dart-review.googlesource.com/c/sdk/+/181421 is safely
307-
// in the rearview mirror in dev/Flutter.
308-
'--ignore-unrecognized-flags',
309-
'--verbosity=error',
310-
'--snapshot=${_resourceProvider.pathContext.absolute(snapshotFile.path)}',
311-
'--snapshot_kind=app-jit',
312-
...compileArgs,
313-
]);
314-
} else {
315-
await snapshot.snapshotValid();
316-
// replace the first argument with the path to the snapshot.
317-
args[0] = _resourceProvider.pathContext.absolute(snapshotFile.path);
318-
}
319-
return Tuple2(_resourceProvider.resolvedExecutable,
320-
needsSnapshot ? snapshot.snapshotCompleted : null);
321-
}
322-
323-
DartToolDefinition(List<String> command, List<String> setupCommand,
324-
String description, this._resourceProvider,
325-
{this.compileArgs = const []})
326-
: assert(compileArgs != null),
327-
super(command, setupCommand, description);
328-
}
329-
330117
/// A configuration class that can interpret [ToolDefinition]s from a YAML map.
331118
class ToolConfiguration {
332119
final Map<String, ToolDefinition> tools;
@@ -396,17 +183,17 @@ class ToolConfiguration {
396183

397184
List<String> findArgs() {
398185
List<String> args;
399-
if (toolMap.containsKey(_kCompileArgsTagName)) {
400-
var compileArgs = toolMap[_kCompileArgsTagName];
186+
if (toolMap.containsKey(compileArgsTagName)) {
187+
var compileArgs = toolMap[compileArgsTagName];
401188
if (compileArgs is String) {
402-
args = [toolMap[_kCompileArgsTagName].toString()];
189+
args = [toolMap[compileArgsTagName].toString()];
403190
} else if (compileArgs is YamlList) {
404191
args =
405192
compileArgs.map<String>((node) => node.toString()).toList();
406193
} else {
407194
throw DartdocOptionError(
408195
'Tool compile arguments must be a list of strings. The tool '
409-
'$name has a $_kCompileArgsTagName entry that is a '
196+
'$name has a $compileArgsTagName entry that is a '
410197
'${compileArgs.runtimeType}');
411198
}
412199
}

0 commit comments

Comments
 (0)