Skip to content

Commit ff91815

Browse files
committed
Write canonicalized SDK
1 parent 3ff8320 commit ff91815

8 files changed

+108
-89
lines changed

lib/src/dartdoc_options.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,8 @@ abstract class DartdocOption<T> {
669669
String get _directoryCurrentPath => resourceProvider.pathContext.current;
670670

671671
/// Calls [valueAt] on the directory this element is defined in.
672-
T valueAtElement(Element element) => valueAt(resourceProvider.getFolder(
673-
resourceProvider.pathContext.canonicalize(
672+
T valueAtElement(Element element) =>
673+
valueAt(resourceProvider.getFolder(resourceProvider.pathContext.normalize(
674674
resourceProvider.pathContext.basename(element.source.fullName))));
675675

676676
/// Adds a DartdocOption to the children of this DartdocOption.

lib/src/model/package.dart

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@ import 'package:dartdoc/src/warnings.dart';
1212
import 'package:path/path.dart' as path;
1313
import 'package:pub_semver/pub_semver.dart';
1414

15-
final RegExp substituteNameVersion = RegExp(r'%([bnv])%');
15+
@Deprecated('Public variable intended to be private; will be removed as early '
16+
'as Dartdoc 1.0.0')
17+
RegExp get substituteNameVersion => Package._substituteNameVersion;
1618

1719
// All hrefs are emitted as relative paths from the output root. We are unable
1820
// to compute them from the page we are generating, and many properties computed
@@ -224,51 +226,56 @@ class Package extends LibraryContainer
224226
String _baseHref;
225227

226228
String get baseHref {
227-
if (_baseHref == null) {
228-
if (documentedWhere == DocumentLocation.remote) {
229-
_baseHref =
230-
config.linkToUrl.replaceAllMapped(substituteNameVersion, (m) {
231-
switch (m.group(1)) {
232-
// Return the prerelease tag of the release if a prerelease,
233-
// or 'stable' otherwise. Mostly coded around
234-
// the Dart SDK's use of dev/stable, but theoretically applicable
235-
// elsewhere.
236-
case 'b':
237-
{
238-
var version = Version.parse(packageMeta.version);
239-
var tag = 'stable';
240-
if (version.isPreRelease) {
241-
// version.preRelease is a List<dynamic> with a mix of
242-
// integers and strings. Given this, handle
243-
// 2.8.0-dev.1.0, 2.9.0-1.0.dev, and similar
244-
// variations.
245-
tag = version.preRelease.whereType<String>().first;
246-
// Who knows about non-SDK packages, but assert that SDKs
247-
// must conform to the known format.
248-
assert(
249-
packageMeta.isSdk == false || int.tryParse(tag) == null,
250-
'Got an integer as string instead of the expected "dev" tag');
251-
}
252-
return tag;
253-
}
254-
case 'n':
255-
return name;
256-
// The full version string of the package.
257-
case 'v':
258-
return packageMeta.version;
259-
default:
260-
assert(false, 'Unsupported case: ${m.group(1)}');
261-
return null;
262-
}
263-
});
264-
if (!_baseHref.endsWith('/')) _baseHref = '${_baseHref}/';
265-
} else {
266-
_baseHref = config.useBaseHref ? '' : HTMLBASE_PLACEHOLDER;
267-
}
229+
if (_baseHref != null) {
230+
return _baseHref;
268231
}
232+
233+
if (documentedWhere == DocumentLocation.remote) {
234+
_baseHref = _remoteBaseHref;
235+
if (!_baseHref.endsWith('/')) _baseHref = '${_baseHref}/';
236+
} else {
237+
_baseHref = config.useBaseHref ? '' : HTMLBASE_PLACEHOLDER;
238+
}
239+
269240
return _baseHref;
270241
}
271242

243+
String get _remoteBaseHref {
244+
return config.linkToUrl.replaceAllMapped(_substituteNameVersion, (m) {
245+
switch (m.group(1)) {
246+
// Return the prerelease tag of the release if a prerelease, or 'stable'
247+
// otherwise. Mostly coded around the Dart SDK's use of dev/stable, but
248+
// theoretically applicable elsewhere.
249+
case 'b':
250+
{
251+
var version = Version.parse(packageMeta.version);
252+
var tag = 'stable';
253+
if (version.isPreRelease) {
254+
// `version.preRelease` is a `List<dynamic>` with a mix of
255+
// integers and strings. Given this, handle
256+
// "2.8.0-dev.1.0, 2.9.0-1.0.dev", and similar variations.
257+
tag = version.preRelease.whereType<String>().first;
258+
// Who knows about non-SDK packages, but SDKs must conform to the
259+
// known format.
260+
assert(packageMeta.isSdk == false || int.tryParse(tag) == null,
261+
'Got an integer as string instead of the expected "dev" tag');
262+
}
263+
return tag;
264+
}
265+
case 'n':
266+
return name;
267+
// The full version string of the package.
268+
case 'v':
269+
return packageMeta.version;
270+
default:
271+
assert(false, 'Unsupported case: ${m.group(1)}');
272+
return null;
273+
}
274+
});
275+
}
276+
277+
static final _substituteNameVersion = RegExp(r'%([bnv])%');
278+
272279
@override
273280
String get href => '$baseHref$filePath';
274281

lib/src/model/package_builder.dart

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -169,17 +169,9 @@ class PubPackageBuilder implements PackageBuilder {
169169
// TODO(jcollins-g): Make use of currently not existing API for managing
170170
// many AnalysisDrivers
171171
// TODO(jcollins-g): make use of DartProject isApi()
172-
_driver = AnalysisDriver(
173-
scheduler,
174-
log,
175-
resourceProvider,
176-
MemoryByteStore(),
177-
FileContentOverlay(),
178-
null,
179-
sourceFactory,
180-
options,
181-
packages: Packages.empty,
182-
);
172+
_driver = AnalysisDriver(scheduler, log, resourceProvider,
173+
MemoryByteStore(), FileContentOverlay(), null, sourceFactory, options,
174+
packages: Packages.empty);
183175
driver.results.listen((_) => logProgress(''));
184176
driver.exceptions.listen((_) {});
185177
scheduler.start();
@@ -439,7 +431,7 @@ class PubPackageBuilder implements PackageBuilder {
439431
}
440432

441433
Future<void> getLibraries(PackageGraph uninitializedPackageGraph) async {
442-
DartSdk findSpecialsSdk = sdk;
434+
var findSpecialsSdk = sdk;
443435
if (embedderSdk != null && embedderSdk.urlMappings.isNotEmpty) {
444436
findSpecialsSdk = embedderSdk;
445437
}

lib/src/package_config_provider.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ import 'dart:io' as io;
88
import 'package:analyzer/file_system/file_system.dart';
99
import 'package:package_config/package_config.dart' as package_config;
1010

11+
/// A provider of PackageConfig-finding methods.
12+
///
13+
/// This provides an abstraction around package_config, which can only work
14+
/// with the physical file system.
1115
abstract class PackageConfigProvider {
1216
Future<package_config.PackageConfig> findPackageConfig(Folder dir);
1317
}

lib/src/package_meta.dart

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,10 @@ abstract class PackageMeta {
9999

100100
p.Context get pathContext => resourceProvider.pathContext;
101101

102-
/// Returns true if this represents a 'Dart' SDK. A package can be part of
103-
/// Dart and Flutter at the same time, but if we are part of a Dart SDK
104-
/// sdkType should never return null.
102+
/// Returns true if this represents a 'Dart' SDK.
103+
///
104+
/// A package can be part of Dart and Flutter at the same time, but if we are
105+
/// part of a Dart SDK, [sdkType] should never return null.
105106
bool get isSdk;
106107

107108
/// Returns 'Dart' or 'Flutter' (preferentially, 'Flutter' when the answer is
@@ -160,11 +161,10 @@ abstract class PubPackageMeta extends PackageMeta {
160161
__sdkDirFilePaths = [];
161162
if (Platform.isWindows) {
162163
for (var paths in __sdkDirFilePathsPosix) {
163-
var windowsPaths = <String>[];
164-
for (var path in paths) {
165-
windowsPaths
166-
.add(p.joinAll(p.Context(style: p.Style.posix).split(path)));
167-
}
164+
var windowsPaths = [
165+
for (var path in paths)
166+
p.joinAll(p.Context(style: p.Style.posix).split(path)),
167+
];
168168
__sdkDirFilePaths.add(windowsPaths);
169169
}
170170
} else {
@@ -176,8 +176,8 @@ abstract class PubPackageMeta extends PackageMeta {
176176

177177
static final _sdkDirParent = <String, Folder>{};
178178

179-
/// Returns the directory of the SDK if the given directory is inside a Dart
180-
/// SDK. Returns null if the directory isn't a subdirectory of the SDK.
179+
/// If [dir] is inside a Dart SDK, returns the directory of the SDK, and `null`
180+
/// otherwise.
181181
static Folder sdkDirParent(Folder dir, ResourceProvider resourceProvider) {
182182
var pathContext = resourceProvider.pathContext;
183183
var dirPathCanonical = pathContext.canonicalize(dir.path);

pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ dependencies:
1919
logging: ^0.11.3+1
2020
process: ^3.0.5
2121
markdown: ^2.1.5
22-
meta: ^1.2.3
22+
meta: ^1.1.8
2323
mustache: ^1.1.0
2424
package_config: '>=0.1.5 <2.0.0'
2525
path: ^1.3.0
@@ -43,4 +43,4 @@ dev_dependencies:
4343
test: ^1.3.0
4444

4545
executables:
46-
dartdoc: null
46+
dartdoc: null

test/comment_processable_test.dart

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,12 @@ void main() {
3838
.writeAsStringSync('''
3939
name: foo
4040
''');
41-
//var sdk = MockSdk(resourceProvider: resourceProvider);
4241
var packageMetaProvider = PackageMetaProvider(
4342
PubPackageMeta.fromElement,
4443
PubPackageMeta.fromFilename,
4544
PubPackageMeta.fromDir,
4645
resourceProvider,
47-
resourceProvider.getFolder(sdkRoot),
46+
resourceProvider.getFolder(resourceProvider.convertPath(sdkRoot)),
4847
);
4948
var optionSet = await DartdocOptionSet.fromOptionGenerators(
5049
'dartdoc', [createDartdocOptions], packageMetaProvider);

test/package_test.dart

Lines changed: 36 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,52 @@ void main() {
2323
FakePackageConfigProvider packageConfigProvider;
2424
PackageGraph packageGraph;
2525

26+
/// Dartdoc has a few indicator files it uses to verify that a directory
27+
/// represents a Dart SDK. These include "bin/dart" and "bin/pub".
28+
void writeSdkBinFiles(Folder root) {
29+
var sdkBinFolder = root.getChildAssumingFolder('bin');
30+
sdkBinFolder.getChildAssumingFile('dart').writeAsStringSync('');
31+
sdkBinFolder.getChildAssumingFile('pub').writeAsStringSync('');
32+
}
33+
2634
void writeSdk() {
2735
mockSdk = MockSdk(resourceProvider: resourceProvider);
28-
sdkFolder = resourceProvider.getFolder(sdkRoot);
29-
var pathContext = resourceProvider.pathContext;
30-
resourceProvider.getFolder(sdkRoot).create();
31-
resourceProvider
32-
.getFile(pathContext.join(sdkRoot, 'bin', 'dart'))
33-
.writeAsStringSync('');
34-
resourceProvider
35-
.getFile(pathContext.join(sdkRoot, 'bin', 'pub'))
36-
.writeAsStringSync('');
36+
// The [MockSdk] only works in non-canonicalized paths, which include
37+
// "C:\sdk", on Windows. Howerver, dartdoc works almost exclusively with
38+
// canonical paths ("c:\sdk"). Copy all MockSdk files to the canonicalized
39+
// path.
40+
for (var l in mockSdk.sdkLibraries) {
41+
var p = l.path;
42+
resourceProvider
43+
.getFile(resourceProvider.pathContext.canonicalize(p))
44+
.writeAsStringSync(resourceProvider.getFile(p).readAsStringSync());
45+
}
46+
sdkFolder = resourceProvider.getFolder(resourceProvider.pathContext
47+
.canonicalize(resourceProvider.convertPath(sdkRoot)))
48+
..create();
49+
sdkFolder.getChildAssumingFile('version').writeAsStringSync('2.9.0');
50+
51+
writeSdkBinFiles(sdkFolder);
52+
writeSdkBinFiles(
53+
resourceProvider.getFolder(resourceProvider.convertPath(sdkRoot)));
3754
}
3855

3956
void writePackage() {
4057
var pathContext = resourceProvider.pathContext;
41-
var projectFolder = resourceProvider
42-
.getFolder(resourceProvider.convertPath('/projects/$packageName'));
58+
var projectsFolder = resourceProvider.getFolder(
59+
pathContext.canonicalize(resourceProvider.convertPath('/projects')));
60+
var projectFolder = projectsFolder.getChildAssumingFolder(packageName)
61+
..create;
4362
projectRoot = projectFolder.path;
44-
projectFolder.create();
45-
resourceProvider
46-
.getFile(pathContext.join(projectRoot, 'pubspec.yaml'))
47-
.writeAsStringSync('''
63+
projectFolder.getChildAssumingFile('pubspec.yaml').writeAsStringSync('''
4864
name: $packageName
65+
version: 0.0.1
4966
''');
50-
resourceProvider
51-
.getFile(
52-
pathContext.join(projectRoot, '.dart_tool', 'package_config.json'))
67+
projectFolder
68+
.getChildAssumingFolder('.dart_tool')
69+
.getChildAssumingFile('package_config.json')
5370
.writeAsStringSync('');
54-
resourceProvider.getFolder(pathContext.join(projectRoot, 'lib')).create();
71+
projectFolder.getChildAssumingFolder('lib').create();
5572
packageConfigProvider.addPackageToConfigFor(
5673
projectRoot, packageName, Uri.file('$projectRoot/'));
5774
}

0 commit comments

Comments
 (0)