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

Support banned relative imports #25

Merged
merged 13 commits into from
May 22, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.3.0
- feat: Support banned relative imports

## 0.2.2
- chore: Upgraded analyzer to 6.4.1
- chore: Upgraded analyzer_plugin to 0.11.3
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,9 @@ For example:
- &repository
name: "repository"
path: "(repository)"
- &useCaseLayer
name: "Domain/UseCases"
path: "(domain/use_cases)"

layers_config:
- layer: *repository
Expand All @@ -151,6 +154,10 @@ For example:
- layer: *presentationLayer
banned:
- *domainLayer
- layer: *useCaseLayer
# You can also ban same origin layers
banned:
- *domainLayer
- layer: *infrastructureLayer
# You can also specify severity per layer
severity: info
Expand Down
3 changes: 2 additions & 1 deletion example/lib/presentation/presentation_class.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:example/infrastructure/data_source/data_source_class.dart';
import 'package:example/infrastructure/repository/repository_class.dart';
// ignore: always_use_package_imports
import '../infrastructure/repository/repository_class.dart';

class PresentationClass {
void call() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,28 @@ class FileAnalyzerImports implements FileAnalyzer {

if (bannedLayers == null) return;

if (import.containsBannedLayer(bannedLayers)) {
final layerConfig = import.getConfigFromLastInPath(config.layersConfig);
final severity = _getNearestSeverity(
layerConfig?.severity,
config.lintSeverity,
config.bannedImportSeverities[currentLayer],
);

yield unitResult.getBannedLayerLint(
import,
currentLayer.displayName,
lintCode,
severity,
showCode: !isCli,
);
if (!resolvedAsBannedImport(import, path, bannedLayers)) {
return;
}

final layerConfig = import.getConfigFromLastInPath(
config.layersConfig,
);
final severity = _getNearestSeverity(
layerConfig?.severity,
config.lintSeverity,
config.bannedImportSeverities[currentLayer],
);

yield unitResult.getBannedLayerLint(
import,
currentLayer.displayName,
lintCode,
severity,
showCode: !isCli,
);
}

return;
}

Expand All @@ -64,7 +69,7 @@ class FileAnalyzerImports implements FileAnalyzer {
ProjectConfiguration config,
) {
for (final layer in config.layers) {
final isLayerNameInPath = path.contains(RegExp(layer.path));
final isLayerNameInPath = RegExp(layer.path).hasMatch(path);
if (isLayerNameInPath) return layer;
}
return null;
Expand All @@ -81,4 +86,16 @@ class FileAnalyzerImports implements FileAnalyzer {

return layerConfigSeverity ?? configLintSeverity;
}

bool resolvedAsBannedImport(
ImportDirective import,
String path,
Set<Layer> bannedLayers,
) {
if (import.isRelative) {
return import.existsInBannedLayers(path, bannedLayers);
} else {
return import.containsBannedLayer(bannedLayers);
}
}
}
2 changes: 1 addition & 1 deletion lib/src/configuration/project_configuration.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class ProjectConfiguration {
}

bool isPathLayer(String path) =>
layers.any((layer) => path.contains(RegExp(layer.path)));
layers.any((layer) => RegExp(layer.path).hasMatch(path));

@override
int get hashCode => Object.hash(
Expand Down
28 changes: 28 additions & 0 deletions lib/src/extensions/import_directive_extensions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ extension ImportDirectiveExtension on ImportDirective {

for (final config in configs) {
final gotConfigForPath = uri.stringValue != null &&
config.layer.path.isNotEmpty &&
RegExp(config.layer.path).hasMatch(uri.stringValue!);
if (gotConfigForPath) {
final index = uri.stringValue!.indexOf(config.layer.path);
Expand All @@ -34,4 +35,31 @@ extension ImportDirectiveExtension on ImportDirective {

return configMap[biggestIndex];
}

bool get isRelative {
if (uri.stringValue == null) return false;
if (uri.stringValue!.isEmpty) return false;
if (Uri.parse(uri.stringValue!).isAbsolute) return false;
return true;
}

bool existsInBannedLayers(String sourceFile, Set<Layer> layers) {
if (uri.stringValue == null) return false;
if (uri.stringValue!.isEmpty) return false;
if (sourceFile.isEmpty) return false;

final absoluteImport = path.normalize(
path.join(sourceFile, '../', uri.stringValue),
);

for (final layer in layers) {
// Always check path (/STH) in order to avoid matching file_STH_a.dart
final segment = '/${layer.path}';
if (RegExp(segment).hasMatch(absoluteImport)) {
return true;
}
}

return false;
}
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ homepage: https://github.com/Iteo/architecture_linter
repository: https://github.com/Iteo/architecture_linter
# Remember, increase also architecture_linter version
# in tools/analyzer_plugin/pubspec.yaml to the same version
version: 0.2.2
version: 0.3.0

environment:
sdk: '>=3.0.0 <4.0.0'
Expand Down
2 changes: 1 addition & 1 deletion tools/analyzer_plugin/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: architecture_linter_analyzer_plugin_loader
description: This pubspec determines the version of the analyzer plugin to load.
version: 0.2.2
version: 0.3.0

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down
Loading