Skip to content
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

fix #2 #10

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,5 @@ jobs:
dartanalyzer --fatal-warnings --no-hints .
- name: Run tests
run: |
exec [ ! -d ./test ] && exit 0
`exec [ ! -d ./test ]` && exit 0
pub run test
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ doc/api/
.idea/

**/*.iml
.devcontainer/*
.vscode/*
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.1.5

- fix #2,implementing topologicalOrdering pub get

## 0.1.4

- implement info command to print GraphViz dor file
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ multipack create gql_link gql_local_state_link --version 0.1.0 --in ./links/
multipack test
multipack test --coverage
multipack build
multipack clean
multipack pubspec clean
```

### `singlepack`
Expand Down
21 changes: 16 additions & 5 deletions bin/multipack.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import "dart:io";

import "package:args/command_runner.dart";
import "package:directed_graph/directed_graph.dart";
import "package:multipack/commands.dart";
import "package:multipack/package.dart";

void main(List<String> arguments) async {
final dependencyGraph = await getPackageGraph(Directory.current);

final orderedPackages = dependencyGraph.sortedTopologicalOrdering.reversed
.map((vertex) => vertex.data)
.toList();
final DirectedGraph<Package> dependencyGraph =
await getPackageGraph(Directory.current);
final List<Package> orderedPackages = getOrderdPackages(dependencyGraph);

final packageNames = orderedPackages
.map(
Expand Down Expand Up @@ -55,3 +54,15 @@ void main(List<String> arguments) async {

await runner.run(arguments);
}

List<Package> getOrderdPackages(DirectedGraph<Package> dependencyGraph) {
final List<Package> packages =
dependencyGraph.edgeMap.keys.map((vertex) => vertex.data).toList();
final topologicalOrdering = dependencyGraph.sortedTopologicalOrdering.reversed
.map((vertex) => vertex.data)
.toList();
final freeDependentPackages =
packages.toSet().difference(topologicalOrdering.toSet());
final orderedPackages = [...topologicalOrdering, ...freeDependentPackages];
return orderedPackages;
}
91 changes: 55 additions & 36 deletions lib/package.dart
Original file line number Diff line number Diff line change
Expand Up @@ -156,29 +156,37 @@ class Package {
String toString() => name;
}

Stream<Package> findPackages(Directory root) =>
findPackageDirectories(root).asyncMap(
(dir) async {
final pubspec = await PubSpec.load(dir);

final dirPath = dir.path;
final rootPath = root.path;

final rootIndex = rootPath.length;
final dirIndex = dirPath.lastIndexOf(Platform.pathSeparator);

return Package(
directory: dir,
namespace: dirPath.substring(
rootIndex == dirIndex ? rootIndex : rootIndex + 1,
dirIndex,
),
name: pubspec.name,
isFlutter: pubspec.allDependencies.containsKey("flutter"),
pubspec: pubspec,
);
},
);
Stream<Package> findPackages(Directory root) {
final rootPath = root.path;
final rootIndex = rootPath.length;
return findPackageDirectories(root).asyncMap(
(dir) async {
final pubspec = await PubSpec.load(dir);

final dirPath = dir.path;
final dirIndex = dirPath.lastIndexOf(Platform.pathSeparator);

return Package(
directory: dir,
namespace: getNamespace(dirPath, rootIndex, dirIndex),
name: pubspec.name,
isFlutter: pubspec.allDependencies.containsKey("flutter"),
pubspec: pubspec,
);
},
);
}

/// The test case(`get_namespace.test.dart`) shows possible DIRPATH situations
String getNamespace(String dirPath, int rootIndex, int dirIndex) {
int namespaceStartIndex = rootIndex == dirIndex ? rootIndex : rootIndex + 1;
if (namespaceStartIndex > dirIndex) namespaceStartIndex = dirIndex;

return dirPath.substring(
namespaceStartIndex,
dirIndex,
);
}

Stream<Directory> findPackageDirectories(Directory root) => root
.list(recursive: true)
Expand All @@ -192,28 +200,39 @@ Stream<Directory> findPackageDirectories(Directory root) => root
(pubspec) => pubspec.parent.absolute,
);

/// step1: Get all packages as `heads` through `findPackages`.
/// It can be converted to a dependency graph,
/// whose head is in `heads` and tail is in `heads.data.pubspec.dependencies`
/// step2: Find a subgraph from dependency graph.
/// The tail of that subgraph is in `heads`
Future<DirectedGraph<Package>> getPackageGraph(Directory root) async {
final vertices = await findPackages(root)
final heads = await findPackages(root)
.map((package) => Vertex<Package>(package))
.toList();

final edges = getEdges(heads);

return DirectedGraph<Package>(
{
for (var vertex in vertices)
vertex: vertex.data.pubspec.allDependencies.keys
.map(
(dep) => vertices.firstWhere(
(v) => v.data.name == dep,
orElse: () => null,
),
)
.where((v) => v != null)
.toList(),
},
edges,
comparator: (
Vertex<Package> vertex1,
Vertex<Package> vertex2,
) =>
vertex1.data.name.compareTo(vertex2.data.name),
);
}

Map<Vertex<Package>, List<Vertex<Package>>> getEdges(
List<Vertex<Package>> heads) {
final headsMap = Map.fromIterables(heads.map((e) => e.data.name), heads);
return {
for (Vertex<Package> head in heads)
// head: tail
head: head.data.pubspec.dependencies.keys
.map(
(dep) => headsMap.containsKey(dep) ? headsMap[dep] : null,
)
.where((v) => v != null)
.toList(),
};
}
8 changes: 5 additions & 3 deletions pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: multipack
description: A tool for monorepo management. Link local packages and execute commands in topological order.
version: 0.1.4
version: 0.1.5
homepage: https://github.com/gql-dart/multipack
environment:
sdk: '>=2.8.0 <3.0.0'
Expand All @@ -9,10 +9,12 @@ dependencies:
args: ^1.6.0
directed_graph: ^0.2.3
meta: ^1.0.0
pubspec: ^0.1.2
pub_semver: ^1.4.4
path: ^1.6.4
pub_semver: ^1.4.4
pubspec: ^0.1.2
dev_dependencies:
gql_pedantic: ^1.0.1
test: ^1.9.4

executables:
multipack: null
36 changes: 36 additions & 0 deletions test/get_namespace_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import "dart:io";
import "package:test/test.dart";
import "package:multipack/package.dart";

void main() {
// group("get namespace", () {
test("pubspec just in root", () {
const String rootPath = "/root";
const String dirPath = "/root";

const rootIndex = rootPath.length;
final int dirIndex = dirPath.lastIndexOf(Platform.pathSeparator);
expect(getNamespace(dirPath, rootIndex, dirIndex), "");
});

// To keep it As before
test("pubspec in subdir of root", () {
const String rootPath = "/root";
const String dirPath = "/root/dir1";

const int rootIndex = rootPath.length;
final int dirIndex = dirPath.lastIndexOf(Platform.pathSeparator);
expect(getNamespace(dirPath, rootIndex, dirIndex), "");
});

// To keep it As before
test("pubspec in Sun of fold", () {
const String rootPath = "/root";
const String dirPath = "/root/dir1/dir2";

const int rootIndex = rootPath.length;
final int dirIndex = dirPath.lastIndexOf(Platform.pathSeparator);
expect(getNamespace(dirPath, rootIndex, dirIndex), "dir1");
});
// });
}