Skip to content

Commit

Permalink
Add build filters (#18)
Browse files Browse the repository at this point in the history
  • Loading branch information
martingeorgiu authored Apr 10, 2024
1 parent 33b200e commit 29f157d
Show file tree
Hide file tree
Showing 21 changed files with 370 additions and 23 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ package as [Mermaid `flowchart`](https://mermaid.js.org/syntax/flowchart.html) d

<img width="536" alt="Screenshot 2023-01-14 at 9 45 33 PM" src="https://user-images.githubusercontent.com/12115586/212524921-5221785f-692d-4464-a230-0f620434e2c5.png">


NOTE: LayerLens shows inside-package dependencies. For cross-package dependencies use `flutter pub deps`.
NOTE: LayerLens shows inside-package dependencies. For cross-package dependencies use `flutter pub deps`.

## Configure layerlens

Expand All @@ -15,7 +14,7 @@ NOTE: LayerLens shows inside-package dependencies. For cross-package dependenci
1. Run `dart pub global activate layerlens`

2. Verify you can run `layerlens`. If you get `command not found`, make sure
your path [contains pub cache](https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path).
your path [contains pub cache](https://dart.dev/tools/pub/cmd/pub-global#running-a-script-from-your-path).

### Configure command for a package

Expand All @@ -30,30 +29,31 @@ To see the diagrams in your IDE:
- **VSCode**: install `Markdown Preview Mermaid Support` extension

- **Android Studio**: enable the "Mermaid" extension in the
[Markdown language settings](https://www.jetbrains.com/help/idea/markdown-reference.html)
[Markdown language settings](https://www.jetbrains.com/help/idea/markdown-reference.html)

## Generate diagrams

1. Run command:

- With global configuration: `layerlens --path <your package root>`
- With global configuration: `layerlens --path <your package root>`

- With package configuration: `dart run layerlens` in the package root
- With package configuration: `dart run layerlens` in the package root

2. Find the generated file DEPENDENCIES.md in each source folder, where
libraries or folders depend on each other.
libraries or folders depend on each other.

3. In VSCode, right click DEPENDENCIES.md and select 'Open Preview'

## CI: re-generate on every GitHub push

1. Add a `dev_dependency` to https://pub.dev/packages/layerlens
2. Copy the content of [run-layerlens.yaml](https://github.com/polina-c/layerlens/blob/main/.github/workflows/run-layerlens.yaml)
to `.github/workflows`.
to `.github/workflows`.

## Alert on circular references

You may want to avoid circular references, because without circles:

1. Code is easier to maintain
2. Chance of memory leaks is smaller
3. Treeshaking (i.e. not including non-used code into build) is more efficient
Expand All @@ -63,6 +63,12 @@ LayerLens marks inverted dependencies (dependencies that create circles) with '!

Also you can add command `dart run layerlens --fail-on-cycles` to the repo's pre-submit bots.

## Build filters

If you want to generate the `DEPENDENCIES.md` only for a specific folders, you can use `--build-filter` option and you should use [glob](https://pub.dev/packages/glob) syntax. For example, to generate the diagram only for the root `lib/` folder, you run following `dart run layerlens --build-filter "lib"`.

You can specify multiple build filters . The mechanism is inspired by `--build-filter` in Dart's [`build_runner`](https://github.com/dart-lang/build/blob/master/docs/partial_builds.md). For example, to run the layerlens for root `lib/` and it's subfolder `lib/subfolder1` run `layerlens --build-filter "lib" --build-filter "lib/subfolder1"`. To generate the entire subtree for a given subfolder you can run following: `layerlens --build-filter "lib/subfolder1" --build-filter "lib/subfolder1/**"`

## Supported languages

While layerlens concepts are language agnostic, for now only `dart` is supported.
Expand Down
14 changes: 14 additions & 0 deletions bin/layerlens.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,14 @@
// limitations under the License.

import 'package:args/args.dart';
import 'package:glob/glob.dart';
import 'package:layerlens/layerlens.dart';

enum _Options {
path('path'),
package('package'),
usage('usage'),
buildFilter('build-filter'),
help('help'),
failOnCycles('fail-on-cycles'),
;
Expand Down Expand Up @@ -57,6 +59,11 @@ void main(List<String> args) async {
defaultsTo: null,
help: 'Package name, that is needed when internal '
'libraries reference each other with `package:` import.',
)
..addMultiOption(
_Options.buildFilter.name,
help:
'Filter for which folders to generate diagrams. Use glob syntax. Default is all folders.\nhttps://github.com/polina-c/layerlens/blob/main/README.md#build-filters',
);

late final ArgResults parsedArgs;
Expand All @@ -75,10 +82,17 @@ void main(List<String> args) async {
return;
}

List<Glob> getBuildFilters() {
final buildFilters = parsedArgs[_Options.buildFilter.name];
if (buildFilters is! List<String>) return [];
return buildFilters.map((filter) => Glob(filter)).toList();
}

final generatedDiagrams = await generateLayering(
rootDir: parsedArgs[_Options.path.name],
packageName: parsedArgs[_Options.package.name],
failOnCycles: parsedArgs[_Options.failOnCycles.name] as bool,
buildFilters: getBuildFilters(),
cyclesFailureMessage: '''Error: cycles detected.
To see the cycles, generate diagrams without --${_Options.failOnCycles.name} and search for '--!--'.
''',
Expand Down
6 changes: 4 additions & 2 deletions example/lib/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ f2.dart--!-->example.dart;
subfolder1-->subfolder2;
```

Inversions in this folder: 1
Inversions including subfolders: 2.
### Inversions
In this folder: 1

Including sub-folders: 2

6 changes: 4 additions & 2 deletions example/lib/subfolder1/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ a.dart-->b.dart;
b.dart--!-->a.dart;
```

Inversions in this folder: 1
Inversions including subfolders: 1.
### Inversions
In this folder: 1

Including sub-folders: 1

6 changes: 4 additions & 2 deletions example/lib/subfolder2/DEPENDENCIES.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ flowchart TD;
c.dart-->d.dart;
```

Inversions in this folder: 0
Inversions including subfolders: 0.
### Inversions
In this folder: 0

Including sub-folders: 0

15 changes: 10 additions & 5 deletions lib/layerlens.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@

import 'dart:io';

import 'src/generator.dart';
import 'src/analyzer.dart';
import 'package:glob/glob.dart';
import 'package:meta/meta.dart';

import 'src/analyzer.dart';
import 'src/code_parser.dart';
import 'package:meta/meta.dart';
import 'src/generator.dart';

typedef ExitFn = Function(int code);

Expand All @@ -31,6 +32,7 @@ Future<int> generateLayering({
required String? packageName,
required bool failOnCycles,
required String cyclesFailureMessage,
required List<Glob> buildFilters,
ExitFn exitFn = exit,
}) async {
final deps = await collectDeps(
Expand All @@ -44,8 +46,11 @@ Future<int> generateLayering({
failOnCycles: failOnCycles,
failureMessage: cyclesFailureMessage,
);
return await MdGenerator(sourceFolder: layering.root, rootDir: rootDir)
.generateFiles();
return await MdGenerator(
sourceFolder: layering.root,
rootDir: rootDir,
buildFilters: buildFilters,
).generateFiles();
}

@visibleForTesting
Expand Down
14 changes: 11 additions & 3 deletions lib/src/generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,21 @@
// limitations under the License.

import 'dart:io';
import 'model.dart';

import 'package:glob/glob.dart';
import 'package:path/path.dart' as path;

import 'model.dart';

class MdGenerator {
final String rootDir;
final SourceFolder sourceFolder;
final List<Glob> buildFilters;

MdGenerator({
required this.rootDir,
required this.sourceFolder,
required this.buildFilters,
});

Future<int> generateFiles() async {
Expand All @@ -43,8 +48,11 @@ class MdGenerator {

final theContent = content(folder);
if (theContent != null) {
file.writeAsStringSync(theContent);
result++;
if (buildFilters.isEmpty ||
buildFilters.any((filter) => filter.matches(folder.fullName))) {
await file.writeAsString(theContent);
result++;
}
}

for (final node in folder.children.values) {
Expand Down
2 changes: 2 additions & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ dependencies:
path: ^1.8.2
surveyor: ^1.0.0-dev.2.0
meta: ^1.12.0
glob: ^2.1.2

dev_dependencies:
file: ^7.0.0
lints: ^2.0.0
test: ^1.21.0
Loading

0 comments on commit 29f157d

Please sign in to comment.