Skip to content

Commit

Permalink
Support workspaces, prepare release (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
kevmoo authored Nov 25, 2024
1 parent c3b5962 commit 324eada
Show file tree
Hide file tree
Showing 16 changed files with 3,154 additions and 1,437 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 4.0.0

- Support (Dart 3.6) workspaces.
- API refactoring to support workspaces.

## 3.0.1

- require at least Dart 3.5
Expand Down
99 changes: 71 additions & 28 deletions lib/src/deps_list.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,19 @@ import 'package:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:string_scanner/string_scanner.dart';

class DepsList extends VersionedEntry {
class DepsList {
static final _sdkLine = RegExp(r'(\w+) SDK (.+)\n');
static final _sourcePackageLine = RegExp('($_pkgName) (.+)\n');
static final _emptyLine = RegExp(r'\n');

final Map<String, Version> sdks;
final Map<String, Map<VersionedEntry, Map<String, VersionConstraint>>>
sections;

Map<VersionedEntry, Map<String, VersionConstraint>> get allEntries =>
CombinedMapView(sections.values);
final Map<String, DepsPackageEntry> packages;
final Map<VersionedEntry, Map<String, VersionConstraint>>
transitiveDependencies;

DepsList._(
super.entry,
this.sdks,
this.sections,
) : super.copy();
DepsList._(this.sdks, this.packages, {required this.transitiveDependencies}) {
for (var entry in packages.values) {
entry._parent = this;
}
}

factory DepsList.parse(String input) {
final scanner = StringScanner(input);
Expand All @@ -36,32 +32,77 @@ class DepsList extends VersionedEntry {
scanSdk();
} while (scanner.matches(_sdkLine));

scanner.expect(_sourcePackageLine, name: 'Source package');
final pkgs = <String, DepsPackageEntry>{};
while (scanner.matches(_packageLine)) {
final entry = DepsPackageEntry._parse(scanner);
pkgs[entry.name] = entry;
}

final section = scanner.matches(_transitiveDepsHeaderLine)
? _scanSection(scanner, headerPattern: _transitiveDepsHeaderLine)
.entries
: <VersionedEntry, Map<String, VersionConstraint>>{};

return DepsList._(
sdks,
pkgs,
transitiveDependencies: section,
);
}

Map<String, dynamic> toJson() => {
'sdks': sdks,
'packages': packages,
'transitiveDependencies':
transitiveDependencies.map((k, v) => MapEntry(k.toString(), v)),
};
}

class DepsPackageEntry extends VersionedEntry {
static final _emptyLine = RegExp(r'\n');

final Map<String, Map<VersionedEntry, Map<String, VersionConstraint>>>
sections;

late final DepsList _parent;

Map<VersionedEntry, Map<String, VersionConstraint>> get allEntries =>
CombinedMapView([
..._parent.packages.values.expand((e) => e.sections.values),
_parent.transitiveDependencies,
]);

DepsPackageEntry._(
super.entry,
this.sections,
) : super.copy();

factory DepsPackageEntry._parse(StringScanner scanner) {
scanner.expect(_packageLine, name: 'Source package');

final sourcePackage = VersionedEntry.fromMatch(scanner.lastMatch!);

final sections =
<String, Map<VersionedEntry, Map<String, VersionConstraint>>>{};

while (scanner.scan(_emptyLine)) {
final section = _scanSection(scanner);
sections[section.key] = section.value;
}
if (!scanner.matches(_sectionHeaderLine)) {
break;
}

assert(scanner.isDone, '${scanner.position} of ${input.length}');
final section = _scanSection(scanner, headerPattern: _sectionHeaderLine);
sections[section.name] = section.entries;
}

return DepsList._(
return DepsPackageEntry._(
sourcePackage,
sdks,
sections,
);
}

Map<String, dynamic> toJson() => {
'name': name,
'version': version.toString(),
'sdks': {
for (var sdk in sdks.entries) sdk.key: sdk.value.toString(),
},
'sections': {
for (var section in sections.entries)
section.key: {
Expand All @@ -87,13 +128,15 @@ const _identifierRegExp = r'[a-zA-Z_]\w*';
/// when publishing a package to pub.dev.
const _pkgName = '$_identifierRegExp(?:\\.$_identifierRegExp)*';

final _sectionHeaderLine = RegExp(r'([a-zA-Z ]+):\n');
final _sectionHeaderLine = RegExp(r'(dependencies|dev dependencies):\n');
final _transitiveDepsHeaderLine = RegExp(r'(transitive dependencies):\n');
final _packageLine = RegExp('($_pkgName) (\\d.+)\n');
final _usageLine = RegExp('- ($_pkgName) (.+)\n');
final _depLine = RegExp(' - ($_pkgName) (.+)\n');

MapEntry<String, Map<VersionedEntry, Map<String, VersionConstraint>>>
_scanSection(StringScanner scanner) {
scanner.expect(_sectionHeaderLine, name: 'section header');
({String name, Map<VersionedEntry, Map<String, VersionConstraint>> entries})
_scanSection(StringScanner scanner, {required Pattern headerPattern}) {
scanner.expect(headerPattern, name: 'section header');
final header = scanner.lastMatch![1]!;

final entries = <VersionedEntry, Map<String, VersionConstraint>>{};
Expand All @@ -115,7 +158,7 @@ MapEntry<String, Map<VersionedEntry, Map<String, VersionConstraint>>>
scanUsage();
} while (scanner.matches(_usageLine));

return MapEntry(header, entries);
return (name: header, entries: entries);
}

class VersionedEntry {
Expand Down
17 changes: 11 additions & 6 deletions lib/src/pub_data_service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,14 @@ class PubDataService extends Service {
@override
final String rootPackageDir;
final bool _debug;
final bool _isFlutterPkg;
late final bool _isFlutterPkg;
late final String packageName;

PubDataService(this.rootPackageDir, {bool debug = false})
: _debug = debug,
_isFlutterPkg = isFlutterPackage(rootPackageDir);
PubDataService(this.rootPackageDir, {bool debug = false}) : _debug = debug {
final details = packageDeets(rootPackageDir);
_isFlutterPkg = details.isFlutterPackage;
packageName = details.packageName;
}

@override
Map<String, dynamic> outdated() {
Expand All @@ -32,9 +35,11 @@ class PubDataService extends Service {
}

@override
DepsList rootDeps() {
DepsPackageEntry rootDeps() {
final commandOutput = _pubCommand(['deps', '-s', 'list']);
return DepsList.parse(commandOutput);
final list = DepsList.parse(commandOutput);

return list.packages[packageName]!;
}

String _pubCommand(List<String> commandArgs) {
Expand Down
7 changes: 5 additions & 2 deletions lib/src/pubspek.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import 'package:pubspec_parse/pubspec_parse.dart' as pubspek show Pubspec;
import 'package:pubspec_parse/pubspec_parse.dart' hide Pubspec;
import 'package:yaml/yaml.dart' as yaml;

bool isFlutterPackage(String packageDir) {
({String packageName, bool isFlutterPackage}) packageDeets(String packageDir) {
final path = p.join(packageDir, 'pubspec.yaml');

final map = yaml.loadYaml(
Expand All @@ -19,7 +19,10 @@ bool isFlutterPackage(String packageDir) {

final pubspec = _Pubspec(map);

return pubspec.usesFlutter;
return (
packageName: pubspec._inner.name,
isFlutterPackage: pubspec.usesFlutter,
);
}

class _Pubspec {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/service.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ abstract class Service {
);
}

DepsList rootDeps();
DepsPackageEntry rootDeps();

Future<Map<String, VizPackage>> getReferencedPackages(
bool flagOutdated,
Expand Down
2 changes: 1 addition & 1 deletion lib/src/version.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: pubviz
version: 3.0.1
version: 4.0.0
description: >-
A tool to visualize package dependencies and version constraints in your Dart
project.
Expand Down
12 changes: 9 additions & 3 deletions test/deps/empty_deps.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
{
"name": "meta",
"version": "1.1.8",
"sdks": {
"Dart": "2.8.0-dev.20.7"
},
"sections": {}
"packages": {
"meta": {
"name": "meta",
"version": "1.1.8",
"sections": {}
}
},
"transitiveDependencies": {}
}

Loading

0 comments on commit 324eada

Please sign in to comment.