Skip to content

Commit 1cc00ac

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

9 files changed

+107
-78
lines changed

analysis_options.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ analyzer:
66
errors:
77
unused_import: warning
88
unused_shown_name: warning
9+
todo: ignore
910
exclude:
1011
- 'doc/**'
1112
- 'lib/src/third_party/pkg/**'

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/documentable.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ abstract class Documentable extends Nameable {
3030
}
3131

3232
/// For a given package, indicate with this enum whether it should be documented
33-
/// [local]ly, whether we should treat the package as [missing] and any references
34-
/// to it made canonical to this package, or [remote], indicating that
35-
/// we can build hrefs to an external source.
33+
/// [local]ly, whether we should treat the package as [missing] and any
34+
/// references to it made canonical to this package, or [remote], indicating
35+
/// that we can build hrefs to an external source.
3636
enum DocumentLocation {
3737
local,
3838
missing,

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: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ class PubPackageBuilder implements PackageBuilder {
439439
}
440440

441441
Future<void> getLibraries(PackageGraph uninitializedPackageGraph) async {
442-
DartSdk findSpecialsSdk = sdk;
442+
var findSpecialsSdk = sdk;
443443
if (embedderSdk != null && embedderSdk.urlMappings.isNotEmpty) {
444444
findSpecialsSdk = embedderSdk;
445445
}

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: 13 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,15 +176,18 @@ 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);
184184
if (!_sdkDirParent.containsKey(dirPathCanonical)) {
185185
_sdkDirParent[dirPathCanonical] = null;
186186
while (dir.exists) {
187187
if (_sdkDirFilePaths.every((List<String> l) {
188+
var path = pathContext.join(dir.path, l.last);
189+
print('checking ${dir.path} for $l: does $path exist? '
190+
'${resourceProvider.getFile(path).exists}');
188191
return l.any((f) =>
189192
resourceProvider.getFile(pathContext.join(dir.path, f)).exists);
190193
})) {

test/comment_processable_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ name: foo
4444
PubPackageMeta.fromFilename,
4545
PubPackageMeta.fromDir,
4646
resourceProvider,
47-
resourceProvider.getFolder(sdkRoot),
47+
resourceProvider.getFolder(resourceProvider.convertPath(sdkRoot)),
4848
);
4949
var optionSet = await DartdocOptionSet.fromOptionGenerators(
5050
'dartdoc', [createDartdocOptions], packageMetaProvider);

test/package_test.dart

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,33 +25,47 @@ void main() {
2525

2626
void writeSdk() {
2727
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('');
28+
for (var l in mockSdk.sdkLibraries) {
29+
var p = l.path;
30+
resourceProvider
31+
.getFile(resourceProvider.pathContext.canonicalize(p))
32+
.writeAsStringSync(resourceProvider.getFile(p).readAsStringSync());
33+
}
34+
sdkFolder = resourceProvider.getFolder(resourceProvider.pathContext
35+
.canonicalize(resourceProvider.convertPath(sdkRoot)))
36+
..create();
37+
sdkFolder.getChildAssumingFile('version').writeAsStringSync('2.9.0');
38+
var sdkBinFolder = sdkFolder.getChildAssumingFolder('bin')..create();
39+
sdkBinFolder.getChildAssumingFile('dart').writeAsStringSync('');
40+
sdkBinFolder.getChildAssumingFile('pub').writeAsStringSync('');
41+
42+
var sdkFolderNonCanon = resourceProvider
43+
.getFolder(resourceProvider.convertPath(sdkRoot))
44+
..create();
45+
var sdkBinFolderNonCanon = sdkFolderNonCanon.getChildAssumingFolder('bin')
46+
..create();
47+
sdkBinFolderNonCanon.getChildAssumingFile('dart').writeAsStringSync('');
48+
sdkBinFolderNonCanon.getChildAssumingFile('pub').writeAsStringSync('');
3749
}
3850

3951
void writePackage() {
4052
var pathContext = resourceProvider.pathContext;
41-
var projectFolder = resourceProvider
42-
.getFolder(resourceProvider.convertPath('/projects/$packageName'));
53+
var projectsFolder = resourceProvider.getFolder(
54+
pathContext.canonicalize(resourceProvider.convertPath('/projects')))
55+
..create();
56+
var projectFolder = projectsFolder.getChildAssumingFolder(packageName)
57+
..create;
4358
projectRoot = projectFolder.path;
44-
projectFolder.create();
45-
resourceProvider
46-
.getFile(pathContext.join(projectRoot, 'pubspec.yaml'))
47-
.writeAsStringSync('''
59+
projectFolder.getChildAssumingFile('pubspec.yaml').writeAsStringSync('''
4860
name: $packageName
61+
version: 0.0.1
4962
''');
50-
resourceProvider
51-
.getFile(
52-
pathContext.join(projectRoot, '.dart_tool', 'package_config.json'))
63+
projectFolder.getChildAssumingFolder('.dart_tool').create();
64+
projectFolder
65+
.getChildAssumingFolder('.dart_tool')
66+
.getChildAssumingFile('package_config.json')
5367
.writeAsStringSync('');
54-
resourceProvider.getFolder(pathContext.join(projectRoot, 'lib')).create();
68+
projectFolder.getChildAssumingFolder('lib').create();
5569
packageConfigProvider.addPackageToConfigFor(
5670
projectRoot, packageName, Uri.file('$projectRoot/'));
5771
}

0 commit comments

Comments
 (0)