Skip to content

Commit

Permalink
Add support for melos mono-repo.
Browse files Browse the repository at this point in the history
  • Loading branch information
dam5s committed Nov 22, 2023
1 parent fed1c95 commit 42a368b
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 11 deletions.
40 changes: 29 additions & 11 deletions lib/cycle_detection/cycle_detector_runner.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';

import 'package:args/args.dart';
import 'package:cyclic_dependency_checks/cycle_detection/melos_paths.dart';

import 'cycle_detector.dart';
import 'module_dependency_graph.dart';
Expand All @@ -24,25 +25,48 @@ class CycleDetectorRunner {
Future<bool> run(List<String> args) async {
final parser = ArgParser()
..addOption('path', abbr: 'p')
..addOption('mono-repo', abbr: 'm')
..addOption('max-depth', abbr: 'd');

final parsedArgs = parser.tryParse(args);
if (parsedArgs == null) {
return false;
}

final path = parsedArgs.getString('path', fallback: '.');
final maxDepth = parsedArgs.tryGetInt('max-depth');
final pathArg = parsedArgs['path'];
final monorepoArg = parsedArgs['mono-repo'];
final maxDepthArg = parsedArgs.tryGetInt('max-depth');

final inferredPaths = await _tryGetPaths(pathArg, monorepoArg);
if (inferredPaths == null) {
printer.err('Failed to infer path from arguments, only one of path or monorepo can be specified');
return false;
}

for (var path in inferredPaths) {
_runForPath(path, maxDepthArg);
}

return true;
}

Future<List<String>?> _tryGetPaths(String? packagePath, String? monorepoPath) async =>
switch ((packagePath, monorepoPath)) {
(null, null) => ['.'],
(String p, null) => [p],
(null, String p) => await MelosPaths.tryGet(p),
(_, _) => null,
};

Future _runForPath(String path, int? maxDepth) async {
final stopwatch = Stopwatch()..start();
final cycles = await detector.detect(path, maxDepth: maxDepth);

stopwatch.stop();

final formattedTime = stopwatch.elapsed.toString().substring(0, 11);

if (cycles.isNotEmpty) {
printer.err('Detected cycles after ${formattedTime}');
printer.err('[$path] Detected cycles after ${formattedTime}');

for (final cycle in cycles) {
printer.err(cycle.path().join(' -> '));
Expand All @@ -51,9 +75,7 @@ class CycleDetectorRunner {
return false;
}

printer.out('No import cycles were detected after ${formattedTime}');

return true;
printer.out('[$path] No cycles detected after ${formattedTime}');
}
}

Expand All @@ -70,10 +92,6 @@ extension _SafeParse on ArgParser {
}

extension _TypeSafeArgs on ArgResults {
String getString(String name, {required String fallback}) {
return this[name] ?? fallback;
}

int? tryGetInt(String name) {
final value = this[name];

Expand Down
26 changes: 26 additions & 0 deletions lib/cycle_detection/melos_paths.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'dart:io';
import 'package:path/path.dart' as path;


final class MelosPaths {
static Future<List<String>?> tryGet(String monorepoPath) async {
final listResult = await Process.run(
'melos',
['list', '-p'],
workingDirectory: monorepoPath,
);

if (listResult.exitCode != 0) {
return null;
}

final output = listResult.stdout as String;
final currentDir = Directory.current;

return output
.split('\n')
.where((p) => p.trim().length > 0)
.map((p) => path.relative(p, from: currentDir.absolute.path))
.toList();
}
}

0 comments on commit 42a368b

Please sign in to comment.