diff --git a/packages/custom_lint/example/example_lint/pubspec.yaml b/packages/custom_lint/example/example_lint/pubspec.yaml index ae33391a..a9964685 100644 --- a/packages/custom_lint/example/example_lint/pubspec.yaml +++ b/packages/custom_lint/example/example_lint/pubspec.yaml @@ -2,7 +2,7 @@ name: custom_lint_example_lint publish_to: none environment: - sdk: '>=2.16.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: analyzer: ">=5.12.0 <7.0.0" diff --git a/packages/custom_lint/example/example_lint/pubspec_overrides.yaml b/packages/custom_lint/example/example_lint/pubspec_overrides.yaml new file mode 100644 index 00000000..fa9db121 --- /dev/null +++ b/packages/custom_lint/example/example_lint/pubspec_overrides.yaml @@ -0,0 +1,8 @@ +# melos_managed_dependency_overrides: custom_lint,custom_lint_builder,custom_lint_core +dependency_overrides: + custom_lint: + path: ../../../custom_lint + custom_lint_builder: + path: ../../../custom_lint_builder + custom_lint_core: + path: ../../../custom_lint_core diff --git a/packages/custom_lint/example/pubspec.yaml b/packages/custom_lint/example/pubspec.yaml index 90b786c8..128c97e3 100644 --- a/packages/custom_lint/example/pubspec.yaml +++ b/packages/custom_lint/example/pubspec.yaml @@ -2,7 +2,7 @@ name: custom_lint_example_app publish_to: none environment: - sdk: '>=2.16.0 <4.0.0' + sdk: '>=3.0.0 <4.0.0' dependencies: riverpod: ^2.0.0 diff --git a/packages/custom_lint/example/pubspec_overrides.yaml b/packages/custom_lint/example/pubspec_overrides.yaml new file mode 100644 index 00000000..761d99b4 --- /dev/null +++ b/packages/custom_lint/example/pubspec_overrides.yaml @@ -0,0 +1,10 @@ +# melos_managed_dependency_overrides: custom_lint,custom_lint_builder,custom_lint_core,custom_lint_example_lint +dependency_overrides: + custom_lint: + path: ../../custom_lint + custom_lint_builder: + path: ../../custom_lint_builder + custom_lint_core: + path: ../../custom_lint_core + custom_lint_example_lint: + path: example_lint diff --git a/packages/custom_lint/lib/src/runner.dart b/packages/custom_lint/lib/src/runner.dart index 7984104f..98e934fc 100644 --- a/packages/custom_lint/lib/src/runner.dart +++ b/packages/custom_lint/lib/src/runner.dart @@ -1,16 +1,12 @@ import 'dart:async'; -import 'package:analyzer/file_system/overlay_file_system.dart'; -import 'package:analyzer/file_system/physical_file_system.dart'; import 'package:analyzer_plugin/protocol/protocol_generated.dart'; import 'package:cli_util/cli_util.dart'; -import 'analyzer_utils/analyzer_utils.dart'; import 'server_isolate_channel.dart'; import 'v2/custom_lint_analyzer_plugin.dart'; import 'workspace.dart'; -const _pluginName = 'custom_lint'; const _analyzerPluginProtocolVersion = '1.0.0-alpha.0'; /// A runner for programmatically interacting with a plugin. @@ -29,10 +25,6 @@ class CustomLintRunner { var _closed = false; - late final _resourceProvider = OverlayResourceProvider( - PhysicalResourceProvider.INSTANCE, - ); - late final _sdkPath = getSdkPath(); /// Starts the plugin and sends the necessary requests for initializing it. @@ -43,7 +35,7 @@ class CustomLintRunner { await channel.sendRequest( PluginVersionCheckParams( - _resourceProvider.getByteStorePath(_pluginName), + '', _sdkPath, _analyzerPluginProtocolVersion, ), diff --git a/packages/custom_lint/test/cli_test.dart b/packages/custom_lint/test/cli_test.dart index caf80b3a..55a232d2 100644 --- a/packages/custom_lint/test/cli_test.dart +++ b/packages/custom_lint/test/cli_test.dart @@ -5,10 +5,9 @@ import 'package:analyzer/error/error.dart'; import 'package:custom_lint/src/output/output_format.dart'; import 'package:test/test.dart'; -import '../bin/custom_lint.dart' as cli; import 'create_project.dart'; import 'equals_ignoring_ansi.dart'; -import 'mock_fs.dart'; +import 'peer_project_meta.dart'; final oyPluginSource = createPluginSource([ TestLintRule( @@ -130,39 +129,48 @@ void main() { for (final format in OutputFormatEnum.values.map((e) => e.name)) { group('With ANSI: $ansi and format: $format', () { test('exits with 0 when no lint and no error are found', () async { - final plugin = - createPlugin(name: 'test_lint', main: emptyPluginSource); + final plugin = createPlugin( + name: 'test_lint', + main: emptyPluginSource, + ); final app = createLintUsage( source: {'lib/main.dart': 'void fn() {}'}, plugins: {'test_lint': plugin.uri}, name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(['--format', format]); - - expect(exitCode, 0); - expect( - out.join(), - completion( - allOf( - matches( - progressMessage( - supportsAnsiEscapes: ansi, - ), - ), - format == 'json' - ? endsWith('{"version":1,"diagnostics":[]}\n') - : endsWith('No issues found!\n'), - ), - ), - ); - expect(err, emitsDone); - }, - currentDirectory: app, - supportsAnsiEscapes: ansi, + + final process = Process.runSync( + 'dart', + [ + customLintBinPath, + '--format', + format, + ], + workingDirectory: app.path, + stderrEncoding: utf8, + stdoutEncoding: utf8, ); + + if (format == 'json') { + expect(process.stdout, ''' +Analyzing... + +{"version":1,"diagnostics":[]} +'''); + } else { + expect( + process.stdout, + ''' +Analyzing... + +No issues found! +''', + ); + } + + expect(process.stderr, isEmpty); + expect(process.exitCode, 0); }); test('CLI lists warnings from all plugins and set exit code', () async { @@ -180,24 +188,28 @@ void main() { name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(['--format', format]); - - final dir = IOOverrides.current!.getCurrentDirectory().path; - expect(err, emitsDone); - expect( - out.join(), - completion( - allOf( - matches( - progressMessage( - supportsAnsiEscapes: ansi, - ), - ), - format == 'json' - ? endsWith('${jsonLints(dir)}\n') - : endsWith(''' + final process = await Process.start( + 'dart', + [ + customLintBinPath, + '--format', + format, + ], + workingDirectory: app.path, + ); + + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); + + expect(err, emitsDone); + expect( + out.join(), + completion( + allOf( + startsWith('Analyzing...'), + format == 'json' + ? endsWith('${jsonLints(app.resolveSymbolicLinksSync())}\n') + : endsWith(''' lib/another.dart:1:6 • Hello world • hello_world • INFO lib/another.dart:1:6 • Oy • oy • INFO lib/main.dart:1:6 • Hello world • hello_world • INFO @@ -205,14 +217,10 @@ void main() { 4 issues found. '''), - ), - ), - ); - expect(exitCode, 1); - }, - currentDirectory: app, - supportsAnsiEscapes: ansi, + ), + ), ); + expect(await process.exitCode, 1); }); }); } @@ -227,33 +235,35 @@ void main() { name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(); + final process = await Process.start( + 'dart', + [customLintBinPath], + workingDirectory: app.path, + ); + + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); - expect(exitCode, 1); - expect( - err.join(), - completion( - allOf([ - matchIgnoringAnsi(contains, ''' + expect( + err.join(), + completion( + allOf([ + matchIgnoringAnsi(contains, ''' /lib/test_lint.dart:1:1: Error: Variables must be declared using the keywords 'const', 'final', 'var' or a type name. Try adding the name of the type of the variable or the keyword 'var'. invalid; ^^^^^^^ '''), - matchIgnoringAnsi(contains, ''' + matchIgnoringAnsi(contains, ''' lib/custom_lint_client.dart:15:29: Error: Undefined name 'createPlugin'. {'test_lint': test_lint.createPlugin, ^^^^^^^^^^^^ '''), - ]), - ), - ); - expect(out, emitsDone); - }, - currentDirectory: app, + ]), + ), ); + expect(out, emitsDone); + expect(await process.exitCode, 1); }); test('exits with 0 when pass argument `--no-fatal-infos`', () async { @@ -265,27 +275,28 @@ lib/custom_lint_client.dart:15:29: Error: Undefined name 'createPlugin'. name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(['--no-fatal-infos']); + final process = await Process.start( + 'dart', + [customLintBinPath, '--no-fatal-infos'], + workingDirectory: app.path, + ); + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); - expect(exitCode, 0); - expect( - out.join(), - completion( - matchIgnoringAnsi(contains, ''' + expect( + out.join(), + completion( + matchIgnoringAnsi(contains, ''' Analyzing... lib/main.dart:1:6 • Hello world • hello_world • INFO 1 issue found. '''), - ), - ); - expect(err, emitsDone); - }, - currentDirectory: app, + ), ); + expect(err, emitsDone); + expect(await process.exitCode, 0); }); test( @@ -308,27 +319,28 @@ Analyzing... name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(['--no-fatal-warnings']); + final process = await Process.start( + 'dart', + [customLintBinPath, '--no-fatal-warnings'], + workingDirectory: app.path, + ); + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); - expect(exitCode, 0); - expect( - out.join(), - completion( - matchIgnoringAnsi(contains, ''' + expect( + out.join(), + completion( + matchIgnoringAnsi(contains, ''' Analyzing... lib/main.dart:1:6 • Hello world • hello_world • WARNING 1 issue found. '''), - ), - ); - expect(err, emitsDone); - }, - currentDirectory: app, + ), ); + expect(err, emitsDone); + expect(await process.exitCode, 0); }); test('supports plugins that do not compile', () async { @@ -347,32 +359,33 @@ Analyzing... name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(); - - expect(exitCode, 1); - expect( - err.join(), - completion( - allOf([ - matchIgnoringAnsi(contains, ''' + final process = await Process.start( + 'dart', + [customLintBinPath], + workingDirectory: app.path, + ); + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); + + expect( + err.join(), + completion( + allOf([ + matchIgnoringAnsi(contains, ''' /lib/test_lint2.dart:1:9: Error: A value of type 'String' can't be assigned to a variable of type 'int'. int x = 'oy'; ^ '''), - matchIgnoringAnsi(contains, ''' + matchIgnoringAnsi(contains, ''' lib/custom_lint_client.dart:17:26: Error: Undefined name 'createPlugin'. 'test_lint2': test_lint2.createPlugin, ^^^^^^^^^^^^ '''), - ]), - ), - ); - expect(out.join(), completion(isEmpty)); - }, - currentDirectory: app, + ]), + ), ); + expect(out.join(), completion(isEmpty)); + expect(await process.exitCode, 1); }); test('Shows prints and exceptions', () async { @@ -405,23 +418,26 @@ lib/custom_lint_client.dart:17:26: Error: Undefined name 'createPlugin'. name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(); - - expect(exitCode, 1); - expect( - out.join(), - completion( - allOf( - contains(''' + final process = await Process.start( + 'dart', + [customLintBinPath], + workingDirectory: app.path, + ); + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); + + expect( + out.join(), + completion( + allOf( + contains(''' [hello_world] [hello_world] [hello_world] Hello [hello_world] world '''), - endsWith( - ''' + endsWith( + ''' Analyzing... lib/another.dart:1:6 • Oy • oy • INFO @@ -430,22 +446,20 @@ Analyzing... 3 issues found. ''', - ), - ), ), - ); - expect( - err.join(), - completion( - contains(''' -Plugin hello_world threw while analyzing ${app.path}/lib/another.dart: + ), + ), + ); + expect( + err.join(), + completion( + contains(''' +Plugin hello_world threw while analyzing ${app.resolveSymbolicLinksSync()}/lib/another.dart: Bad state: fail #0 hello_world.run. (package:test_lint/test_lint.dart:'''), - ), - ); - }, - currentDirectory: app, + ), ); + expect(await process.exitCode, 1); }); test('Sorts lints by line then column the code', () async { @@ -533,19 +547,22 @@ void other() { name: 'test_app', ); - await runWithIOOverride( - (out, err) async { - await cli.entrypoint(); + final process = await Process.start( + 'dart', + [customLintBinPath], + workingDirectory: app.path, + ); + final out = process.stdout.map(utf8.decode); + final err = process.stderr.map(utf8.decode); - expect(exitCode, 1); - expect( - err.join(), - completion(isEmpty), - ); + expect( + err.join(), + completion(isEmpty), + ); - expect( - out.join(), - completion(''' + expect( + out.join(), + completion(''' Analyzing... lib/main.dart:1:1 • e • e • ERROR @@ -567,9 +584,7 @@ Analyzing... 16 issues found. '''), - ); - }, - currentDirectory: app, ); + expect(await process.exitCode, 1); }); } diff --git a/packages/custom_lint/test/mock_fs.dart b/packages/custom_lint/test/mock_fs.dart index 95170507..9b198d75 100644 --- a/packages/custom_lint/test/mock_fs.dart +++ b/packages/custom_lint/test/mock_fs.dart @@ -135,6 +135,14 @@ class _MockFs extends IOOverrides { @override Directory getCurrentDirectory() => _directory; + @override + FileSystemEntityType fseGetTypeSync(String path, bool followLinks) { + return Zone.current.parent!.run(() { + // Workaround to https://github.com/dart-lang/sdk/issues/54741 + return FileSystemEntity.typeSync(path, followLinks: followLinks); + }); + } + @override void setCurrentDirectory(String path) { _directory = Directory(path); diff --git a/packages/custom_lint/test/server_test.dart b/packages/custom_lint/test/server_test.dart index a9043041..41ef8515 100644 --- a/packages/custom_lint/test/server_test.dart +++ b/packages/custom_lint/test/server_test.dart @@ -12,7 +12,7 @@ import 'matchers.dart'; import 'mock_fs.dart'; import 'run_plugin.dart'; -final lintRuleWithFilesToAnalayze = createPluginSource([ +final lintRuleWithFilesToAnalyze = createPluginSource([ TestLintRule( code: 'hello_world', message: 'Hello world', @@ -27,7 +27,7 @@ void main() { test('List warnings for all files combined', () async { final plugin = createPlugin( name: 'test_lint', - main: lintRuleWithFilesToAnalayze, + main: lintRuleWithFilesToAnalyze, ); final app = createLintUsage( @@ -318,7 +318,7 @@ if (node.name.lexeme == "fail") { name: 'test_app', ); - await runWithIOOverride((out, err) async { + await runWithIOOverride(currentDirectory: app, (out, err) async { final runner = await startRunnerForApp( app, // Ignoring errors as we are handling them later diff --git a/packages/custom_lint_builder/example/example_lint/pubspec_overrides.yaml b/packages/custom_lint_builder/example/example_lint/pubspec_overrides.yaml new file mode 100644 index 00000000..f2f7e08e --- /dev/null +++ b/packages/custom_lint_builder/example/example_lint/pubspec_overrides.yaml @@ -0,0 +1,8 @@ +# melos_managed_dependency_overrides: custom_lint,custom_lint_builder,custom_lint_core +dependency_overrides: + custom_lint: + path: ../../../custom_lint + custom_lint_builder: + path: ../.. + custom_lint_core: + path: ../../../custom_lint_core diff --git a/packages/custom_lint_builder/example/pubspec_overrides.yaml b/packages/custom_lint_builder/example/pubspec_overrides.yaml new file mode 100644 index 00000000..e859a8af --- /dev/null +++ b/packages/custom_lint_builder/example/pubspec_overrides.yaml @@ -0,0 +1,10 @@ +# melos_managed_dependency_overrides: custom_lint,custom_lint_builder,custom_lint_builder_example_lint,custom_lint_core +dependency_overrides: + custom_lint: + path: ../../custom_lint + custom_lint_builder: + path: ../../custom_lint_builder + custom_lint_builder_example_lint: + path: example_lint + custom_lint_core: + path: ../../custom_lint_core