From 342156c03a98cb7260f35e2992c8725411ffc852 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 23 Jan 2024 08:52:40 +0000 Subject: [PATCH 01/10] feat: define `BrickIgnore` class --- packages/mason/lib/src/brick_ignore.dart | 93 +++++++++++++++++++ packages/mason/pubspec.yaml | 1 + .../mason/test/src/brick_ignore_test.dart | 80 ++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 packages/mason/lib/src/brick_ignore.dart create mode 100644 packages/mason/test/src/brick_ignore_test.dart diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart new file mode 100644 index 000000000..2aacc46b9 --- /dev/null +++ b/packages/mason/lib/src/brick_ignore.dart @@ -0,0 +1,93 @@ +import 'dart:collection'; +import 'dart:io'; + +import 'package:glob/glob.dart'; +import 'package:mason/mason.dart'; +import 'package:meta/meta.dart'; +import 'package:path/path.dart' as path; + +/// {@template brick_ignore} +/// A file that is created at the root of the brick to ignore files +/// and directories during bundling. +/// +/// Only those directories under `__brick__` can be ignored. +/// +/// For example, given the following brick directory: +/// +/// ```txt +/// __brick__/ +/// ├─ HELLO.md +/// └─ goodbye.dart +/// brick.yaml +/// .brickignore +/// README.md +/// ``` +/// +/// And the following `.brickignore` file content: +/// +/// ```txt +/// **.md +/// ``` +/// +/// The `HELLO.md` file will be ignored during bundling, but `goodbye.dart` will +/// not be ignored. Those other files not under `__brick__` are not bundled, +/// hence they can not be ignored. +/// +/// See also: +/// +/// * [createBundle], which creates a [MasonBundle] from a brick directory. +/// {@endtemplate} +@internal +class BrickIgnore { + BrickIgnore._({ + required Iterable globs, + required String path, + required String brickDirectoryPath, + }) : _globs = UnmodifiableListView(globs), + _path = path, + _brickDirectoryPath = brickDirectoryPath; + + /// Creates a [BrickIgnore] from a [File]. + factory BrickIgnore.fromFile(File file) { + final lines = file.readAsLinesSync(); + final globs = lines.map(Glob.new); + + final brickDirectoryPath = path.join(file.parent.path, BrickYaml.dir); + + return BrickIgnore._( + globs: globs, + path: file.path, + brickDirectoryPath: brickDirectoryPath, + ); + } + + /// The name of the file to be created at the root of the brick. + /// `brick.yaml` + static const file = '.brickignore'; + + final UnmodifiableListView _globs; + + /// The absolute path to the ignore file. + final String _path; + + /// The absolute absolute path to the directory where all brick templated + /// files are located. + /// + /// See also: + /// + /// * [BrickYaml.dir], which is the name of the directory where the templated + /// brick files are located. + final String _brickDirectoryPath; + + /// Whether or not the [filePath] is ignored. + /// + /// Immediately returns false if the [filePath] is not within the brick + /// directory (`__brick__`). Otherwise, checks if the [filePath] matches + /// any of the globs in the ignore file. + bool isIgnored(String filePath) { + if (!path.isWithin(_brickDirectoryPath, filePath)) return false; + + final relativePath = path.relative(filePath, from: path.dirname(_path)); + return _globs.any((glob) => glob.matches(relativePath)); + } +} diff --git a/packages/mason/pubspec.yaml b/packages/mason/pubspec.yaml index a244e97b7..a43d03dd5 100644 --- a/packages/mason/pubspec.yaml +++ b/packages/mason/pubspec.yaml @@ -17,6 +17,7 @@ dependencies: collection: ^1.15.0 convert: ^3.1.0 crypto: ^3.0.1 + glob: ^2.1.2 http: '>=0.13.3 <2.0.0' json_annotation: ^4.8.1 mason_logger: ^0.2.11 diff --git a/packages/mason/test/src/brick_ignore_test.dart b/packages/mason/test/src/brick_ignore_test.dart new file mode 100644 index 000000000..5ee7b219c --- /dev/null +++ b/packages/mason/test/src/brick_ignore_test.dart @@ -0,0 +1,80 @@ +import 'dart:io'; + +import 'package:mason/src/brick_ignore.dart'; +import 'package:path/path.dart' as path; +import 'package:test/test.dart'; + +void main() { + group('$BrickIgnore', () { + late File brickIgnoreFile; + + setUp(() { + final temporaryDirectory = Directory.systemTemp.createTempSync(); + addTearDown(() => temporaryDirectory.deleteSync(recursive: true)); + + brickIgnoreFile = + File(path.join(temporaryDirectory.path, BrickIgnore.file)) + ..createSync(); + }); + + test('fromFile returns normally', () { + expect( + () => BrickIgnore.fromFile(brickIgnoreFile), + returnsNormally, + ); + }); + + group('isIgnored', () { + test('returns true when the file is ignored', () { + brickIgnoreFile.writeAsStringSync('**.md'); + final brickIgnore = BrickIgnore.fromFile(brickIgnoreFile); + + final ignoredFilePath = path.join( + brickIgnoreFile.parent.path, + '__brick__', + 'HELLO.md', + ); + + expect( + brickIgnore.isIgnored(ignoredFilePath), + isTrue, + reason: '`HELLO.md` is under `__brick__` and is ignored by `**.md`', + ); + }); + + test( + 'returns false when the file to be ignored is not under __brick__', + () { + brickIgnoreFile.writeAsStringSync('**.md'); + final brickIgnore = BrickIgnore.fromFile(brickIgnoreFile); + + final ignoredFilePath = + path.join(brickIgnoreFile.parent.path, 'HELLO.md'); + + expect( + brickIgnore.isIgnored(ignoredFilePath), + isFalse, + reason: '`HELLO.md` is not under `__brick__`', + ); + }, + ); + + test('returns false when the file is not ignored', () { + brickIgnoreFile.writeAsStringSync(''); + final brickIgnore = BrickIgnore.fromFile(brickIgnoreFile); + + final ignoredFilePath = path.join( + brickIgnoreFile.parent.path, + '__brick__', + 'HELLO.md', + ); + + expect( + brickIgnore.isIgnored(ignoredFilePath), + isFalse, + reason: '`HELLO.md` is under `__brick__` and there are no ignores', + ); + }); + }); + }); +} From 6061f3f961e64c9ad82c4d8ada16fa4688095c17 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 23 Jan 2024 08:56:27 +0000 Subject: [PATCH 02/10] docs: update comments --- packages/mason/lib/src/brick_ignore.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 2aacc46b9..07f3bfda4 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -7,10 +7,10 @@ import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; /// {@template brick_ignore} -/// A file that is created at the root of the brick to ignore files -/// and directories during bundling. +/// A file that defines what brick files or directories should be ignored during +/// bundling. /// -/// Only those directories under `__brick__` can be ignored. +/// Only those directories and files under `__brick__` can be ignored. /// /// For example, given the following brick directory: /// From 34f9d1c729cba93bfafceeb10328eace5aafd231 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 23 Jan 2024 08:57:20 +0000 Subject: [PATCH 03/10] docs: removed unused template --- packages/mason/lib/src/brick_ignore.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 07f3bfda4..dd686260b 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -6,7 +6,6 @@ import 'package:mason/mason.dart'; import 'package:meta/meta.dart'; import 'package:path/path.dart' as path; -/// {@template brick_ignore} /// A file that defines what brick files or directories should be ignored during /// bundling. /// @@ -36,7 +35,6 @@ import 'package:path/path.dart' as path; /// See also: /// /// * [createBundle], which creates a [MasonBundle] from a brick directory. -/// {@endtemplate} @internal class BrickIgnore { BrickIgnore._({ From 1f0b52a7e5573c011354dd2ec867e3918e1bcd0a Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 23 Jan 2024 09:11:24 +0000 Subject: [PATCH 04/10] docs: removed typo double "absolute" --- packages/mason/lib/src/brick_ignore.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index dd686260b..98cf556e2 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -68,8 +68,8 @@ class BrickIgnore { /// The absolute path to the ignore file. final String _path; - /// The absolute absolute path to the directory where all brick templated - /// files are located. + /// The absolute path to the directory where all brick templated files are + /// located. /// /// See also: /// From 60dcf73878ef3336e37adf4398884c0fca988b90 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Tue, 23 Jan 2024 09:12:05 +0000 Subject: [PATCH 05/10] docs: improved [file] documentation --- packages/mason/lib/src/brick_ignore.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 98cf556e2..787b4c7ed 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -59,8 +59,7 @@ class BrickIgnore { ); } - /// The name of the file to be created at the root of the brick. - /// `brick.yaml` + /// The name of the file to be used as the ignore file. static const file = '.brickignore'; final UnmodifiableListView _globs; From 96a25b34e3eeb176566858a774b7f591e65c1c5e Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Thu, 8 Feb 2024 11:08:58 +0000 Subject: [PATCH 06/10] feat: support comments --- packages/mason/lib/src/brick_ignore.dart | 4 ++- .../mason/test/src/brick_ignore_test.dart | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 787b4c7ed..9db2e8f6a 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -48,7 +48,9 @@ class BrickIgnore { /// Creates a [BrickIgnore] from a [File]. factory BrickIgnore.fromFile(File file) { final lines = file.readAsLinesSync(); - final globs = lines.map(Glob.new); + final globs = lines.where((line) => !line.startsWith('#')).map( + (line) => Glob(line.trim()), + ); final brickDirectoryPath = path.join(file.parent.path, BrickYaml.dir); diff --git a/packages/mason/test/src/brick_ignore_test.dart b/packages/mason/test/src/brick_ignore_test.dart index 5ee7b219c..603b0a9d7 100644 --- a/packages/mason/test/src/brick_ignore_test.dart +++ b/packages/mason/test/src/brick_ignore_test.dart @@ -75,6 +75,36 @@ void main() { reason: '`HELLO.md` is under `__brick__` and there are no ignores', ); }); + + test('returns as expected when the file has comments', () { + brickIgnoreFile.writeAsStringSync(''' +# Some comment +**.md +'''); + final brickIgnore = BrickIgnore.fromFile(brickIgnoreFile); + + final ignoredFilePath = path.join( + brickIgnoreFile.parent.path, + '__brick__', + 'HELLO.md', + ); + expect( + brickIgnore.isIgnored(ignoredFilePath), + isTrue, + reason: '`HELLO.md` is under `__brick__` and is ignored by `**.md`', + ); + + final notIgnoredFilePath = path.join( + brickIgnoreFile.parent.path, + '__brick__', + 'main.dart', + ); + expect( + brickIgnore.isIgnored(notIgnoredFilePath), + isFalse, + reason: '`main.dart` is under `__brick__` and there are no ignores', + ); + }); }); }); } From e035d40082c601e0f2ce3655ca902fb783acd040 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Thu, 8 Feb 2024 11:09:21 +0000 Subject: [PATCH 07/10] test: updated comment test --- packages/mason/test/src/brick_ignore_test.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/mason/test/src/brick_ignore_test.dart b/packages/mason/test/src/brick_ignore_test.dart index 603b0a9d7..51ea3f669 100644 --- a/packages/mason/test/src/brick_ignore_test.dart +++ b/packages/mason/test/src/brick_ignore_test.dart @@ -80,6 +80,7 @@ void main() { brickIgnoreFile.writeAsStringSync(''' # Some comment **.md +# **.dart '''); final brickIgnore = BrickIgnore.fromFile(brickIgnoreFile); From 84440dd27eb449b585eab1ea5c98f84d472c79d5 Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Thu, 8 Feb 2024 11:11:14 +0000 Subject: [PATCH 08/10] refactor: defined _commentCharacter --- packages/mason/lib/src/brick_ignore.dart | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 9db2e8f6a..3875bae9e 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -48,9 +48,9 @@ class BrickIgnore { /// Creates a [BrickIgnore] from a [File]. factory BrickIgnore.fromFile(File file) { final lines = file.readAsLinesSync(); - final globs = lines.where((line) => !line.startsWith('#')).map( - (line) => Glob(line.trim()), - ); + final globs = lines + .where((line) => !line.startsWith(_commentCharacter)) + .map((line) => Glob(line.trim())); final brickDirectoryPath = path.join(file.parent.path, BrickYaml.dir); @@ -64,6 +64,17 @@ class BrickIgnore { /// The name of the file to be used as the ignore file. static const file = '.brickignore'; + /// The character that indicates a comment in the ignore file. + /// + /// If the line starts with this character, the line is considered a comment + /// and is ignored. + /// + /// For example: + /// ```txt + /// # This is a comment + /// ``` + static const _commentCharacter = '#'; + final UnmodifiableListView _globs; /// The absolute path to the ignore file. From 4c79392130af141195c2191e5cc27bc8f3e075fb Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Thu, 8 Feb 2024 11:12:37 +0000 Subject: [PATCH 09/10] docs: add note about comments --- packages/mason/lib/src/brick_ignore.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/mason/lib/src/brick_ignore.dart b/packages/mason/lib/src/brick_ignore.dart index 3875bae9e..ebe7864b4 100644 --- a/packages/mason/lib/src/brick_ignore.dart +++ b/packages/mason/lib/src/brick_ignore.dart @@ -25,6 +25,7 @@ import 'package:path/path.dart' as path; /// And the following `.brickignore` file content: /// /// ```txt +/// # Ignore all markdown files /// **.md /// ``` /// @@ -32,6 +33,9 @@ import 'package:path/path.dart' as path; /// not be ignored. Those other files not under `__brick__` are not bundled, /// hence they can not be ignored. /// +/// Note that the ignore file supports comments, which are lines that start +/// with a `#` character. +/// /// See also: /// /// * [createBundle], which creates a [MasonBundle] from a brick directory. From 3d701fd3fb54ad56e62dfe2c5a649f63745cfddc Mon Sep 17 00:00:00 2001 From: Alejandro Santiago Date: Thu, 8 Feb 2024 11:13:08 +0000 Subject: [PATCH 10/10] test: update example file to goodbye.dart --- packages/mason/test/src/brick_ignore_test.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/mason/test/src/brick_ignore_test.dart b/packages/mason/test/src/brick_ignore_test.dart index 51ea3f669..e44f045a0 100644 --- a/packages/mason/test/src/brick_ignore_test.dart +++ b/packages/mason/test/src/brick_ignore_test.dart @@ -98,12 +98,13 @@ void main() { final notIgnoredFilePath = path.join( brickIgnoreFile.parent.path, '__brick__', - 'main.dart', + 'goodbye.dart', ); expect( brickIgnore.isIgnored(notIgnoredFilePath), isFalse, - reason: '`main.dart` is under `__brick__` and there are no ignores', + reason: + '`goodbye.dart` is under `__brick__` and there are no ignores', ); }); });