Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,32 @@ permissions:
jobs:
build:
uses: Workiva/gha-dart-oss/.github/workflows/build.yaml@v0.1.14
with:
sdk: 3.12.2

dart:
strategy:
fail-fast: false
matrix:
os: [ ubuntu, windows ]
sdk: [ 2.19.6, stable ]
sdk: [ stable ]
name: Dart ${{ matrix.sdk }} on ${{ matrix.os }}
runs-on: ${{ matrix.os }}-latest
steps:
- uses: actions/checkout@v6
- uses: actions/checkout@v7
- uses: dart-lang/setup-dart@v1
with:
sdk: ${{ matrix.sdk }}
- name: Install dependencies
run: dart pub get
- name: Validate dependencies
run: dart run dependency_validator
run: |
dart pub global activate dependency_validator
dart pub global run dependency_validator
- name: Analysis
run: dart run dart_dev analyze
- name: Formatting
if: ${{ matrix.sdk == 'stable' && matrix.os == 'ubuntu' }}
if: ${{ matrix.os == 'ubuntu' }}
run: dart run dart_dev format --check
- name: Tests
run: dart run dart_dev test ${{ matrix.sdk != '2.19.6' && '--test-args="--exclude-tags dart2"' || '' }}
run: dart run dart_dev test
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dart 3.12.2
4 changes: 0 additions & 4 deletions analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ analyzer:
language:
strict-inference: true
strict-raw-types: true
strong-mode:
implicit-casts: true
implicit-dynamic: true

linter:
rules:
- avoid_types_on_closure_parameters
Expand Down
13 changes: 6 additions & 7 deletions doc/tools/analyze-tool.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `AnalyzeTool`

Statically analyzes the current project by running the `dartanalyzer`.
Statically analyzes the current project by running `dart analyze`.

## Usage

Expand All @@ -18,13 +18,13 @@ final config = {

## Default behavior

By default this tool will run `dartanalyzer .` which will analyze all dart files
By default this tool will run `dart analyze .` which will analyze all dart files
in the current project.

## Configuration

`AnalyzeTool` supports one configuration option which is the list of args to
pass to the `dartanalyzer` process:
pass to `dart analyze`:

```dart
// tool/dart_dev/config.dart
Expand All @@ -44,13 +44,12 @@ final config = {

The `analysis_options.yaml` configuration file
[supports excluding files][analysis-exclude]. However, there is an
[open issue with the `dartanalyzer` CLI][analyzer-exclude-issue] because it does
[open issue with the `dart analyze` CLI][analyzer-exclude-issue] because it does
not respect this list.

If your project has files that need to be excluded from analysis (e.g. generated
files), use the [`TuneupCheckTool`][tuneup-check-tool]. It uses the
`tuneup` package to run analysis instead of `dartanalyzer` and it properly
respects the exclude rules defined in `analysis_options.yaml`.
files), use the [`TuneupCheckTool`][tuneup-check-tool] which properly respects
the exclude rules defined in `analysis_options.yaml`.

## Command-line options

Expand Down
11 changes: 5 additions & 6 deletions doc/tools/format-tool.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# `FormatTool`

Formats dart files in the current project by running `dartfmt`.
Formats dart files in the current project by running `dart format`.

## Usage

Expand All @@ -18,7 +18,7 @@ final config = {

## Default behavior

By default this tool will run `dartfmt -w .` which will format all dart files in
By default this tool will run `dart format .` which will format all dart files in
the current project.

## Configuration
Expand All @@ -44,11 +44,10 @@ final config = {
};
```

### Using the `dart_style` package instead of `dartfmt`
### Using the `dart_style` package instead of `dart format`

Some projects like to depend on a specific version of the `dart_style` package
and use its `format` executable rather than the `dartfmt` provided by the Dart
SDK.
and use its `format` executable rather than `dart format` from the SDK.

```dart
// tool/dart_dev/config.dart
Expand All @@ -75,7 +74,7 @@ final config = {
```bash
$ ddev format
[INFO] Running subprocess...
dartfmt -w --fix .
dart format --fix .
----------------------------
```

Expand Down
2 changes: 1 addition & 1 deletion doc/tools/tuneup-check-tool.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Statically analyzes the current project via the `tuneup` package.

This is intended to be used as a drop-in replacement to the
[`AnalyzeTool`][analyze-tool] to workaround an
[open issue with `dartanalyzer` and excluding files][analyzer-exclude-issue] via
[open issue with `dart analyze` and excluding files][analyzer-exclude-issue] via
`analysis_options.yaml`.

Add `tuneup` as a dev dependency to your project:
Expand Down
2 changes: 0 additions & 2 deletions lib/src/core_config.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
/// A `tool/dart_dev/config.dart` base configuration with the core Dart
/// developer tasks. Intended to help standardize dart_dev configuration and
/// command-line usage across Dart projects.
library dart_dev.src.core_config;

import 'package:dart_dev/dart_dev.dart';

Map<String, DevTool> get coreConfig => {
Expand Down
58 changes: 15 additions & 43 deletions lib/src/tools/analyze_tool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,21 @@ import 'package:logging/logging.dart';
import '../dart_dev_tool.dart';
import '../utils/arg_results_utils.dart';
import '../utils/assert_no_positional_args_nor_args_after_separator.dart';
import '../utils/dart_semver_version.dart';
import '../utils/executables.dart' as exe;
import '../utils/logging.dart';
import '../utils/process_declaration.dart';
import '../utils/run_process_and_ensure_exit.dart';

final _log = Logger('Analyze');

/// A dart_dev tool that runs the `dartanalyzer` or `dart analyze` on the current project.
/// If the `useDartAnalyze` flag is not specified it will default to `dartanalyzer`.
/// A dart_dev tool that runs `dart analyze` on the current project.
///
/// To use this tool in your project, include it in the dart_dev config in
/// `tool/dart_dev/config.dart`:
/// import 'package:dart_dev/dart_dev.dart';
///
/// final config = {
/// 'analyze': AnalyzeTool() ..useDartAnalyze = true,
/// 'analyze': AnalyzeTool(),
/// };
///
/// This will make it available via the `dart_dev` command-line app like so:
Expand All @@ -39,25 +37,23 @@ final _log = Logger('Analyze');
/// 'analyze': AnalyzeTool()
/// ..analyzerArgs = ['--fatal-infos']
/// ..include = [Glob('.'), Glob('other/**.dart')],
/// ..useDartAnalyze = true
/// };
///
/// It is also possible to run this tool directly in a dart script:
/// AnalyzeTool().run();
class AnalyzeTool extends DevTool {
/// The args to pass to the `dartanalyzer` or `dart analyze` process run by this tool.
/// The args to pass to the `dart analyze` process run by this tool.
///
/// Run `dartanalyzer -h -v` or `dart analyze -h -v` to see all available args.
/// Run `dart analyze -h -v` to see all available args.
List<String>? analyzerArgs;

/// The globs to include as entry points to run static analysis on.
///
/// The default is `.` (e.g. `dartanalyzer .`) which runs analysis on all Dart
/// The default is `.` (e.g. `dart analyze .`) which runs analysis on all Dart
/// files in the current working directory.
List<Glob>? include;

/// The default tool for analysis will be `dartanalyzer` unless opted in here
/// to utilize `dart analyze`.
@Deprecated('dart analyze is always used in Dart 3+. This field is ignored.')
bool? useDartAnalyze;

// ---------------------------------------------------------------------------
Expand All @@ -69,8 +65,8 @@ class AnalyzeTool extends DevTool {
..addOption(
'analyzer-args',
help:
'Args to pass to the "dartanalyzer" or "dart analyze" process.\n'
'Run "dartanalyzer -h -v" or `dart analyze -h -v" to see all available options.',
'Args to pass to the "dart analyze" process.\n'
'Run "dart analyze -h -v" to see all available options.',
);

@override
Expand All @@ -83,17 +79,13 @@ class AnalyzeTool extends DevTool {
context ?? DevToolExecutionContext(),
configuredAnalyzerArgs: analyzerArgs,
include: include,
useDartAnalyze: !dartVersionHasDartanalyzer
? true
: useDartAnalyze ?? false,
),
log: _log,
);
}
}

/// Returns a combined list of args for the `dartanalyzer`
/// or `dart analyze` process.
/// Returns a combined list of args for the `dart analyze` process.
///
/// If [configuredAnalyzerArgs] is non-null, they will be included first.
///
Expand All @@ -105,17 +97,11 @@ class AnalyzeTool extends DevTool {
Iterable<String> buildArgs({
ArgResults? argResults,
List<String>? configuredAnalyzerArgs,
bool useDartAnalyze = false,
bool verbose = false,
}) {
final args = <String>[
// Combine all args that should be passed through to the analyzer in
// this order:
// 1. The analyze command if using dart analyze
if (useDartAnalyze) 'analyze',
// 2. Statically configured args from [AnalyzeTool.analyzerArgs]
'analyze',
...?configuredAnalyzerArgs,
// 3. Args passed to --analyzer-args
...?splitSingleOptionValue(argResults, 'analyzer-args'),
];
if (verbose && !args.contains('-v') && !args.contains('--verbose')) {
Expand Down Expand Up @@ -161,9 +147,6 @@ Iterable<String> buildEntrypoints({List<Glob>? include, String? root}) {
/// If non-null, [path] will override the current working directory for any
/// operations that require it. This is intended for use by tests.
///
/// If true, [useDartAnalyze] will utilize `dart analyze` for analysis.
/// If null, it will default to utilze `dartanalyzer`.
///
/// The [AnalyzeTool] can be tested almost completely via this function by
/// enumerating all of the possible parameter variations and making assertions
/// on the declarative output.
Expand All @@ -172,53 +155,42 @@ ProcessDeclaration buildProcess(
List<String>? configuredAnalyzerArgs,
List<Glob>? include,
String? path,
bool useDartAnalyze = false,
}) {
final argResults = context.argResults;
if (argResults != null) {
final analyzerUsed = useDartAnalyze ? 'dart analyze' : 'dartanalyzer';
assertNoPositionalArgsNorArgsAfterSeparator(
argResults,
context.usageException,
commandName: context.commandName,
usageFooter:
'Arguments can be passed to the "$analyzerUsed" process via '
'Arguments can be passed to the "dart analyze" process via '
'the --analyzer-args option.',
);
}
var executable = useDartAnalyze ? exe.dart : exe.dartanalyzer;
final args = buildArgs(
argResults: context.argResults,
configuredAnalyzerArgs: configuredAnalyzerArgs,
verbose: context.verbose,
useDartAnalyze: useDartAnalyze,
);
final entrypoints = buildEntrypoints(include: include, root: path);
logCommand(
args,
entrypoints,
verbose: context.verbose,
useDartAnalyzer: useDartAnalyze,
);
return ProcessDeclaration(executable, [
logCommand(args, entrypoints, verbose: context.verbose);
return ProcessDeclaration(exe.dart, [
...args,
...entrypoints,
], mode: ProcessStartMode.inheritStdio);
}

/// Logs the `dartanalyzer` or `dart analyze` command that will be run by [AnalyzeTool] so that
/// Logs the `dart analyze` command that will be run by [AnalyzeTool] so that
/// consumers can run it directly for debugging purposes.
///
/// Unless [verbose] is true, the list of entrypoints will be abbreviated to
/// avoid an unnecessarily long log.
void logCommand(
Iterable<String> args,
Iterable<String> entrypoints, {
bool useDartAnalyzer = false,
bool verbose = false,
}) {
final exeAndArgs =
'${useDartAnalyzer ? "dart" : "dartanalyzer"} ${args.join(' ')}'.trim();
final exeAndArgs = 'dart ${args.join(' ')}'.trim();

if (entrypoints.length <= 5 || verbose) {
logSubprocessHeader(_log, '$exeAndArgs ${entrypoints.join(' ')}');
Expand Down
Loading
Loading