Skip to content

Introduce basic glob support to option handling #2365

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 54 additions & 37 deletions lib/src/dartdoc_options.dart
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,17 @@ class _YamlFileData {
_YamlFileData(this.data, this.canonicalDirectoryPath);
}

/// An enum to specify the multiple different kinds of data an option might
/// represent.
enum OptionKind {
other, // Make no assumptions about the option data; it may be of any type
// or semantic.
file, // Option data references a filename or filenames with strings.
dir, // Option data references a directory name or names with strings.
glob, // Option data references globs with strings that may cover many
// filenames and/or directories.
}

/// Some DartdocOption subclasses need to keep track of where they
/// got the value from; this class contains those intermediate results
/// so that error messages can be more useful.
Expand Down Expand Up @@ -503,10 +514,15 @@ abstract class DartdocOption<T> {
final String name;

/// Set to true if this option represents the name of a directory.
final bool isDir;
bool get isDir => optionIs == OptionKind.dir;

/// Set to true if this option represents the name of a file.
final bool isFile;
bool get isFile => optionIs == OptionKind.file;

/// Set to true if this option represents a glob.
bool get isGlob => optionIs == OptionKind.glob;

final OptionKind optionIs;

/// Set to true if DartdocOption subclasses should validate that the
/// directory or file exists. Does not imply validation of [defaultsTo],
Expand All @@ -515,11 +531,13 @@ abstract class DartdocOption<T> {

final ResourceProvider resourceProvider;

DartdocOption(this.name, this.defaultsTo, this.help, this.isDir, this.isFile,
DartdocOption(this.name, this.defaultsTo, this.help, this.optionIs,
this.mustExist, this._convertYamlToType, this.resourceProvider) {
assert(!(isDir && isFile));
if (isDir || isFile) assert(_isString || _isListString || _isMapString);
if (isDir || isFile || isGlob) {
assert(_isString || _isListString || _isMapString);
}
if (mustExist) {
// Globs by definition don't have to exist.
assert(isDir || isFile);
}
}
Expand Down Expand Up @@ -604,7 +622,7 @@ abstract class DartdocOption<T> {
/// For a [List<String>] or [String] value, if [isDir] or [isFile] is set,
/// resolve paths in value relative to canonicalPath.
T _handlePathsInContext(_OptionValueWithContext<Object> valueWithContext) {
if (valueWithContext?.value == null || !(isDir || isFile)) {
if (valueWithContext?.value == null || !(isDir || isFile || isGlob)) {
return valueWithContext?.value;
}
_validatePaths(valueWithContext);
Expand Down Expand Up @@ -715,11 +733,10 @@ class DartdocOptionFileSynth<T> extends DartdocOption<T>
String name, this._compute, ResourceProvider resourceprovider,
{bool mustExist = false,
String help = '',
bool isDir = false,
bool isFile = false,
OptionKind optionIs = OptionKind.other,
bool parentDirOverridesChild,
ConvertYamlToType<T> convertYamlToType})
: super(name, null, help, isDir, isFile, mustExist, convertYamlToType,
: super(name, null, help, optionIs, mustExist, convertYamlToType,
resourceprovider) {
_parentDirOverridesChild = parentDirOverridesChild;
}
Expand Down Expand Up @@ -765,12 +782,10 @@ class DartdocOptionArgSynth<T> extends DartdocOption<T>
bool mustExist = false,
String help = '',
bool hide = false,
bool isDir = false,
bool isFile = false,
OptionKind optionIs = OptionKind.other,
bool negatable = false,
bool splitCommas})
: super(name, null, help, isDir, isFile, mustExist, null,
resourceProvider) {
: super(name, null, help, optionIs, mustExist, null, resourceProvider) {
_hide = hide;
_negatable = negatable;
_splitCommas = splitCommas;
Expand Down Expand Up @@ -818,10 +833,8 @@ class DartdocOptionSyntheticOnly<T> extends DartdocOption<T>
String name, this._compute, ResourceProvider resourceProvider,
{bool mustExist = false,
String help = '',
bool isDir = false,
bool isFile = false})
: super(
name, null, help, isDir, isFile, mustExist, null, resourceProvider);
OptionKind optionIs = OptionKind.other})
: super(name, null, help, optionIs, mustExist, null, resourceProvider);
}

abstract class DartdocSyntheticOption<T> implements DartdocOption<T> {
Expand Down Expand Up @@ -856,7 +869,8 @@ typedef OptionGenerator = Future<List<DartdocOption<Object>>> Function(
/// option itself.
class DartdocOptionSet extends DartdocOption<void> {
DartdocOptionSet(String name, ResourceProvider resourceProvider)
: super(name, null, null, false, false, false, null, resourceProvider);
: super(
name, null, null, OptionKind.other, false, null, resourceProvider);

/// Asynchronous factory that is the main entry point to initialize Dartdoc
/// options for use.
Expand Down Expand Up @@ -908,11 +922,10 @@ class DartdocOptionArgOnly<T> extends DartdocOption<T>
bool mustExist = false,
String help = '',
bool hide = false,
bool isDir = false,
bool isFile = false,
OptionKind optionIs = OptionKind.other,
bool negatable = false,
bool splitCommas})
: super(name, defaultsTo, help, isDir, isFile, mustExist, null,
: super(name, defaultsTo, help, optionIs, mustExist, null,
resourceProvider) {
_hide = hide;
_negatable = negatable;
Expand Down Expand Up @@ -949,12 +962,11 @@ class DartdocOptionArgFile<T> extends DartdocOption<T>
bool mustExist = false,
String help = '',
bool hide = false,
bool isDir = false,
bool isFile = false,
OptionKind optionIs = OptionKind.other,
bool negatable = false,
bool parentDirOverridesChild = false,
bool splitCommas})
: super(name, defaultsTo, help, isDir, isFile, mustExist, null,
: super(name, defaultsTo, help, optionIs, mustExist, null,
resourceProvider) {
_abbr = abbr;
_hide = hide;
Expand Down Expand Up @@ -1007,12 +1019,11 @@ class DartdocOptionFileOnly<T> extends DartdocOption<T>
String name, T defaultsTo, ResourceProvider resourceProvider,
{bool mustExist = false,
String help = '',
bool isDir = false,
bool isFile = false,
OptionKind optionIs = OptionKind.other,
bool parentDirOverridesChild = false,
ConvertYamlToType<T> convertYamlToType})
: super(name, defaultsTo, help, isDir, isFile, mustExist,
convertYamlToType, resourceProvider) {
: super(name, defaultsTo, help, optionIs, mustExist, convertYamlToType,
resourceProvider) {
_parentDirOverridesChild = parentDirOverridesChild;
}

Expand Down Expand Up @@ -1260,8 +1271,10 @@ abstract class _DartdocArgOption<T> implements DartdocOption<T> {

T retval;
// Unlike in _DartdocFileOption, we throw here on inputs being invalid
// rather than silently proceeding. TODO(jcollins-g): throw on input
// formatting for files too?
// rather than silently proceeding. This is because the user presumably
// typed something wrong on the command line and can therefore fix it.
// dartdoc_option.yaml files from other packages may not be fully in the
// user's control.
if (_isBool || _isListString || _isString) {
retval = _argResults[argName];
} else if (_isInt) {
Expand Down Expand Up @@ -1566,7 +1579,7 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
}, resourceProvider,
help: 'Remove text from libraries with the following names.'),
DartdocOptionArgFile<String>('examplePathPrefix', null, resourceProvider,
isDir: true,
optionIs: OptionKind.dir,
help: 'Prefix for @example paths.\n(defaults to the project root)',
mustExist: true),
DartdocOptionArgFile<List<String>>('exclude', [], resourceProvider,
Expand All @@ -1580,7 +1593,7 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
(DartdocSyntheticOption<String> option, Folder dir) =>
resolveTildePath(Platform.environment['FLUTTER_ROOT']),
resourceProvider,
isDir: true,
optionIs: OptionKind.dir,
help: 'Root of the Flutter SDK, specified from environment.',
mustExist: true),
DartdocOptionArgOnly<bool>('hideSdkText', false, resourceProvider,
Expand All @@ -1592,7 +1605,7 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
help: 'Library names to generate docs for.', splitCommas: true),
DartdocOptionArgFile<List<String>>(
'includeExternal', null, resourceProvider,
isFile: true,
optionIs: OptionKind.file,
help:
'Additional (external) dart files to include; use "dir/fileName", '
'as in lib/material.dart.',
Expand All @@ -1605,7 +1618,9 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
'HTML into dartdoc output.'),
DartdocOptionArgOnly<String>(
'input', resourceProvider.pathContext.current, resourceProvider,
isDir: true, help: 'Path to source directory', mustExist: true),
optionIs: OptionKind.dir,
help: 'Path to source directory',
mustExist: true),
DartdocOptionSyntheticOnly<String>('inputDir',
(DartdocSyntheticOption<String> option, Folder dir) {
if (option.parent['sdkDocs'].valueAt(dir)) {
Expand All @@ -1614,7 +1629,7 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
return option.parent['input'].valueAt(dir);
}, resourceProvider,
help: 'Path to source directory (with override if --sdk-docs)',
isDir: true,
optionIs: OptionKind.dir,
mustExist: true),
DartdocOptionSet('linkTo', resourceProvider)
..addAll([
Expand Down Expand Up @@ -1656,7 +1671,7 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
]),
DartdocOptionArgOnly<String>('output',
resourceProvider.pathContext.join('doc', 'api'), resourceProvider,
isDir: true, help: 'Path to output directory.'),
optionIs: OptionKind.dir, help: 'Path to output directory.'),
DartdocOptionSyntheticOnly<PackageMeta>(
'packageMeta',
(DartdocSyntheticOption<PackageMeta> option, Folder dir) {
Expand Down Expand Up @@ -1691,7 +1706,9 @@ Future<List<DartdocOption<Object>>> createDartdocOptions(
}
return packageMetaProvider.defaultSdkDir.path;
}, packageMetaProvider.resourceProvider,
help: 'Path to the SDK directory.', isDir: true, mustExist: true),
help: 'Path to the SDK directory.',
optionIs: OptionKind.dir,
mustExist: true),
DartdocOptionArgFile<bool>(
'showUndocumentedCategories', false, resourceProvider,
help: "Label categories that aren't documented", negatable: true),
Expand Down
10 changes: 5 additions & 5 deletions lib/src/generator/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ Future<List<DartdocOption<Object>>> createGeneratorOptions(
var resourceProvider = packageMetaProvider.resourceProvider;
return [
DartdocOptionArgFile<List<String>>('footer', [], resourceProvider,
isFile: true,
optionIs: OptionKind.file,
help:
'Paths to files with content to add to page footers, but possibly '
'outside of dedicated footer elements for the generator (e.g. '
Expand All @@ -64,13 +64,13 @@ Future<List<DartdocOption<Object>>> createGeneratorOptions(
mustExist: true,
splitCommas: true),
DartdocOptionArgFile<List<String>>('footerText', [], resourceProvider,
isFile: true,
optionIs: OptionKind.file,
help: 'Paths to files with content to add to page footers (next to the '
'package name and version).',
mustExist: true,
splitCommas: true),
DartdocOptionArgFile<List<String>>('header', [], resourceProvider,
isFile: true,
optionIs: OptionKind.file,
help: 'Paths to files with content to add to page headers.',
splitCommas: true),
DartdocOptionArgOnly<bool>('prettyIndexJson', false, resourceProvider,
Expand All @@ -79,7 +79,7 @@ Future<List<DartdocOption<Object>>> createGeneratorOptions(
'larger, but it\'s also easier to diff.',
negatable: false),
DartdocOptionArgFile<String>('favicon', null, resourceProvider,
isFile: true,
optionIs: OptionKind.file,
help: 'A path to a favicon for the generated docs.',
mustExist: true),
DartdocOptionArgOnly<String>('relCanonicalPrefix', null, resourceProvider,
Expand All @@ -88,7 +88,7 @@ Future<List<DartdocOption<Object>>> createGeneratorOptions(
'Consider using if building many versions of the docs for public '
'SEO; learn more at https://goo.gl/gktN6F.'),
DartdocOptionArgOnly<String>('templatesDir', null, resourceProvider,
isDir: true,
optionIs: OptionKind.dir,
mustExist: true,
hide: true,
help:
Expand Down
4 changes: 2 additions & 2 deletions lib/src/source_linker.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ Future<List<DartdocOption<Object>>> createSourceLinkerOptions(
DartdocOptionSet('linkToSource', resourceProvider)
..addAll([
DartdocOptionArgFile<List<String>>('excludes', [], resourceProvider,
isDir: true,
optionIs: OptionKind.dir,
help:
'A list of directories to exclude from linking to a source code repository.'),
// TODO(jcollins-g): Use [DartdocOptionArgSynth], possibly in combination with a repository type and the root directory, and get revision number automatically
DartdocOptionArgOnly<String>('revision', null, resourceProvider,
help: 'Revision number to insert into the URI.'),
DartdocOptionArgFile<String>('root', null, resourceProvider,
isDir: true,
optionIs: OptionKind.dir,
help:
'Path to a local directory that is the root of the repository we link to. All source code files under this directory will be linked.'),
DartdocOptionArgFile<String>('uriTemplate', null, resourceProvider,
Expand Down
Loading