chore: adopt Dart 3.9 toolchain — honest floor + tall-style reformat (T-353)
Raise the declared minimums in pubspec.yaml to what our deps already require: Flutter >=3.35.0 / Dart >=3.9.0 (was 3.19.0 / 3.5.0). alchemist 0.12 needs Flutter 3.32; Dart 3.9 first ships in Flutter 3.35, so 3.35 is the binding floor. Pin the exact build toolchain in .fvmrc (Flutter 3.44.1). Moving to the Dart 3.9 language level switches `dart format` to the new "tall" style and enables two new lints. This commit is the resulting mechanical churn, isolated from any behaviour change: - whole-tree `dart format` reformat (tall style) - `dart fix` for unnecessary_underscores + use_null_aware_elements No runtime behaviour change; `make test` green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -122,7 +122,10 @@ void main() {
|
||||
d.register(
|
||||
'git.checkout',
|
||||
(req) async => IpcResponse.ok(id: req.id, data: const {}),
|
||||
schema: CommandSchema(positional: const ['ref'], args: {'ref': ArgSpec(pattern: RegExp(r'^\w+$'))}),
|
||||
schema: CommandSchema(
|
||||
positional: const ['ref'],
|
||||
args: {'ref': ArgSpec(pattern: RegExp(r'^\w+$'))},
|
||||
),
|
||||
);
|
||||
|
||||
final tools = d.mcpTools();
|
||||
|
||||
@@ -138,9 +138,7 @@ void main() {
|
||||
await call('editor.open', {'path': 'a.md'});
|
||||
await call('editor.open', {'path': 'b.md'});
|
||||
final r = await call('editor.list');
|
||||
final names = [
|
||||
for (final b in (r.data['buffers'] as List).cast<Map>()) b['path'],
|
||||
];
|
||||
final names = [for (final b in (r.data['buffers'] as List).cast<Map>()) b['path']];
|
||||
expect(names, containsAll(['a.md', 'b.md']));
|
||||
});
|
||||
|
||||
@@ -204,14 +202,14 @@ void main() {
|
||||
test('editor.set-selection clamps and applies', () async {
|
||||
await call('editor.open', {'path': 'doc.md'});
|
||||
final r = await call('editor.set-selection', {
|
||||
'selection': {'start': 0, 'end': 3}
|
||||
'selection': {'start': 0, 'end': 3},
|
||||
});
|
||||
expect(r.ok, isTrue);
|
||||
});
|
||||
|
||||
test('editor.set-selection without an id or active buffer returns not-found', () async {
|
||||
final r = await call('editor.set-selection', {
|
||||
'selection': {'start': 0, 'end': 1}
|
||||
'selection': {'start': 0, 'end': 1},
|
||||
});
|
||||
expect(r.ok, isFalse);
|
||||
expect(r.error!.kind, 'not_found');
|
||||
@@ -226,7 +224,7 @@ void main() {
|
||||
expect(read1.data['content'], 'replaced');
|
||||
final r2 = await call('editor.set-content', {
|
||||
'text': 'short',
|
||||
'selection': {'start': 1, 'end': 99}
|
||||
'selection': {'start': 1, 'end': 99},
|
||||
});
|
||||
expect(r2.ok, isTrue);
|
||||
});
|
||||
|
||||
@@ -67,9 +67,7 @@ void main() {
|
||||
test('files.ls into a subdirectory returns its contents', () async {
|
||||
final r = await call('files.ls', const {'path': 'lib'});
|
||||
expect(r.ok, isTrue);
|
||||
final names = [
|
||||
for (final e in (r.data['entries'] as List).cast<Map>()) e['name'],
|
||||
];
|
||||
final names = [for (final e in (r.data['entries'] as List).cast<Map>()) e['name']];
|
||||
expect(names, ['main.dart']);
|
||||
});
|
||||
|
||||
|
||||
@@ -40,8 +40,8 @@ void main() {
|
||||
(
|
||||
'git.stage',
|
||||
const {
|
||||
'paths': ['file.txt']
|
||||
}
|
||||
'paths': ['file.txt'],
|
||||
},
|
||||
),
|
||||
('git.stage-all', const <String, Object?>{}),
|
||||
('git.unstage', const <String, Object?>{}),
|
||||
@@ -53,8 +53,8 @@ void main() {
|
||||
(
|
||||
'git.discard',
|
||||
const {
|
||||
'paths': ['file.txt']
|
||||
}
|
||||
'paths': ['file.txt'],
|
||||
},
|
||||
),
|
||||
('git.commit', const {'message': 'hi'}),
|
||||
('git.stash', const <String, Object?>{}),
|
||||
|
||||
@@ -13,23 +13,11 @@ void main() {
|
||||
setUp(() async {
|
||||
sandbox = await Directory.systemTemp.createTemp('clide-git-cmd-test-');
|
||||
await Process.run('git', ['init'], workingDirectory: sandbox.path);
|
||||
await Process.run(
|
||||
'git',
|
||||
['config', 'user.email', 'test@test.com'],
|
||||
workingDirectory: sandbox.path,
|
||||
);
|
||||
await Process.run(
|
||||
'git',
|
||||
['config', 'user.name', 'Test'],
|
||||
workingDirectory: sandbox.path,
|
||||
);
|
||||
await Process.run('git', ['config', 'user.email', 'test@test.com'], workingDirectory: sandbox.path);
|
||||
await Process.run('git', ['config', 'user.name', 'Test'], workingDirectory: sandbox.path);
|
||||
await File('${sandbox.path}/file.txt').writeAsString('hello\n');
|
||||
await Process.run('git', ['add', '.'], workingDirectory: sandbox.path);
|
||||
await Process.run(
|
||||
'git',
|
||||
['commit', '-m', 'init'],
|
||||
workingDirectory: sandbox.path,
|
||||
);
|
||||
await Process.run('git', ['commit', '-m', 'init'], workingDirectory: sandbox.path);
|
||||
|
||||
sink = RecordingEventSink();
|
||||
dispatcher = DaemonDispatcher();
|
||||
@@ -64,7 +52,7 @@ void main() {
|
||||
test('git.stage + git.status shows staged file', () async {
|
||||
await File('${sandbox.path}/new.txt').writeAsString('x');
|
||||
final stage = await call('git.stage', {
|
||||
'paths': ['new.txt']
|
||||
'paths': ['new.txt'],
|
||||
});
|
||||
expect(stage.ok, isTrue);
|
||||
|
||||
@@ -82,10 +70,10 @@ void main() {
|
||||
test('git.unstage removes from staging', () async {
|
||||
await File('${sandbox.path}/new.txt').writeAsString('x');
|
||||
await call('git.stage', {
|
||||
'paths': ['new.txt']
|
||||
'paths': ['new.txt'],
|
||||
});
|
||||
final unstage = await call('git.unstage', {
|
||||
'paths': ['new.txt']
|
||||
'paths': ['new.txt'],
|
||||
});
|
||||
expect(unstage.ok, isTrue);
|
||||
|
||||
@@ -97,7 +85,7 @@ void main() {
|
||||
test('git.commit creates a commit', () async {
|
||||
await File('${sandbox.path}/c.txt').writeAsString('x');
|
||||
await call('git.stage', {
|
||||
'paths': ['c.txt']
|
||||
'paths': ['c.txt'],
|
||||
});
|
||||
final r = await call('git.commit', {'message': 'test commit'});
|
||||
expect(r.ok, isTrue);
|
||||
@@ -121,7 +109,7 @@ void main() {
|
||||
test('git.diff --staged returns staged diffs', () async {
|
||||
await File('${sandbox.path}/file.txt').writeAsString('modified\n');
|
||||
await call('git.stage', {
|
||||
'paths': ['file.txt']
|
||||
'paths': ['file.txt'],
|
||||
});
|
||||
final r = await call('git.diff', {'staged': true});
|
||||
expect(r.ok, isTrue);
|
||||
@@ -139,7 +127,7 @@ void main() {
|
||||
test('git.discard restores a file', () async {
|
||||
await File('${sandbox.path}/file.txt').writeAsString('changed');
|
||||
final r = await call('git.discard', {
|
||||
'paths': ['file.txt']
|
||||
'paths': ['file.txt'],
|
||||
});
|
||||
expect(r.ok, isTrue);
|
||||
final content = await File('${sandbox.path}/file.txt').readAsString();
|
||||
@@ -155,12 +143,9 @@ void main() {
|
||||
test('mutations emit git.changed events', () async {
|
||||
await File('${sandbox.path}/e.txt').writeAsString('x');
|
||||
await call('git.stage', {
|
||||
'paths': ['e.txt']
|
||||
'paths': ['e.txt'],
|
||||
});
|
||||
expect(
|
||||
sink.events,
|
||||
contains(predicate<IpcEvent>((e) => e.kind == 'git.changed')),
|
||||
);
|
||||
expect(sink.events, contains(predicate<IpcEvent>((e) => e.kind == 'git.changed')));
|
||||
});
|
||||
|
||||
test('git.stage-all stages everything', () async {
|
||||
@@ -192,7 +177,7 @@ void main() {
|
||||
await File('${sandbox.path}/file.txt').writeAsString('hello\nworld\n');
|
||||
await File('${sandbox.path}/other.txt').writeAsString('o');
|
||||
final r = await call('git.diff', {
|
||||
'paths': ['file.txt']
|
||||
'paths': ['file.txt'],
|
||||
});
|
||||
expect(r.ok, isTrue);
|
||||
final diffs = r.data['diffs'] as List;
|
||||
|
||||
@@ -17,19 +17,14 @@ void main() {
|
||||
void wire({bool liveUi = true, Set<String> found = const {'docs/diagram.png'}, bool withResolver = true}) {
|
||||
published = [];
|
||||
d = DaemonDispatcher();
|
||||
registerImageCommands(
|
||||
d,
|
||||
() {
|
||||
if (!liveUi) return null;
|
||||
return (publisher, channel, data) => published.add((publisher: publisher, channel: channel, data: data));
|
||||
},
|
||||
resolve: withResolver ? (path) => found.contains(path) ? '/abs/$path' : null : null,
|
||||
);
|
||||
registerImageCommands(d, () {
|
||||
if (!liveUi) return null;
|
||||
return (publisher, channel, data) => published.add((publisher: publisher, channel: channel, data: data));
|
||||
}, resolve: withResolver ? (path) => found.contains(path) ? '/abs/$path' : null : null);
|
||||
}
|
||||
|
||||
Future<IpcResponse> show(List<String> positional, {Map<String, Object?>? flags}) => d.dispatch(
|
||||
IpcRequest(id: '1', cmd: 'image.show', args: {'positional': positional, if (flags != null) 'flags': flags}),
|
||||
);
|
||||
Future<IpcResponse> show(List<String> positional, {Map<String, Object?>? flags}) =>
|
||||
d.dispatch(IpcRequest(id: '1', cmd: 'image.show', args: {'positional': positional, 'flags': ?flags}));
|
||||
|
||||
test('resolves a workspace-relative path and publishes an image message', () async {
|
||||
wire();
|
||||
|
||||
@@ -75,10 +75,7 @@ void main() {
|
||||
expect(viaText.ok, isTrue);
|
||||
expect(viaText.data['written'], greaterThan(0));
|
||||
|
||||
final viaBase64 = await call('pane.write', {
|
||||
'id': id,
|
||||
'bytes_b64': base64Encode(utf8.encode('def')),
|
||||
});
|
||||
final viaBase64 = await call('pane.write', {'id': id, 'bytes_b64': base64Encode(utf8.encode('def'))});
|
||||
expect(viaBase64.ok, isTrue);
|
||||
});
|
||||
|
||||
@@ -115,7 +112,7 @@ void main() {
|
||||
|
||||
test('pane.spawn rejects non-string argv entries', () async {
|
||||
final r = await call('pane.spawn', const {
|
||||
'argv': ['/bin/sh', 42]
|
||||
'argv': ['/bin/sh', 42],
|
||||
});
|
||||
expect(r.ok, isFalse);
|
||||
expect(r.error!.message, contains('strings'));
|
||||
@@ -262,7 +259,7 @@ void main() {
|
||||
|
||||
test('merges PTY panes and UI tabs in one list', () async {
|
||||
await call('pane.spawn', {
|
||||
'argv': const ['/bin/cat']
|
||||
'argv': const ['/bin/cat'],
|
||||
});
|
||||
final r = await call('pane.list', const {});
|
||||
final panes = (r.data['panes'] as List).cast<Map>();
|
||||
|
||||
@@ -17,10 +17,7 @@ void main() {
|
||||
late _FakeResizer resizer;
|
||||
|
||||
setUp(() {
|
||||
resizer = _FakeResizer(
|
||||
slots: {'sidebar': 200, 'context': 240, 'workspace': 800},
|
||||
editorRatio: 0.35,
|
||||
);
|
||||
resizer = _FakeResizer(slots: {'sidebar': 200, 'context': 240, 'workspace': 800}, editorRatio: 0.35);
|
||||
dispatcher = DaemonDispatcher();
|
||||
registerPanelCommands(dispatcher, resizer);
|
||||
});
|
||||
|
||||
@@ -49,7 +49,7 @@ void main() {
|
||||
const {
|
||||
'ids': ['T-1'],
|
||||
'status': 'done',
|
||||
}
|
||||
},
|
||||
),
|
||||
('pql.tickets.board', const <String, Object?>{}),
|
||||
('pql.plan.status', const <String, Object?>{}),
|
||||
|
||||
@@ -181,11 +181,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('pql.decisions.show forwards withRefs / withTickets', () async {
|
||||
final r = await call('pql.decisions.show', {
|
||||
'id': 'D-1',
|
||||
'withRefs': true,
|
||||
'withTickets': true,
|
||||
});
|
||||
final r = await call('pql.decisions.show', {'id': 'D-1', 'withRefs': true, 'withTickets': true});
|
||||
expect(r.ok, isTrue);
|
||||
expect(r.data['id'], 'D-1');
|
||||
});
|
||||
@@ -198,12 +194,7 @@ void main() {
|
||||
});
|
||||
|
||||
test('pql.tickets.list with filters narrows + shows status', () async {
|
||||
final r = await call('pql.tickets.list', {
|
||||
'status': 'done',
|
||||
'team': 'whatever',
|
||||
'assigned': 'no-one',
|
||||
'decision': 'D-1',
|
||||
});
|
||||
final r = await call('pql.tickets.list', {'status': 'done', 'team': 'whatever', 'assigned': 'no-one', 'decision': 'D-1'});
|
||||
expect(r.ok, isTrue);
|
||||
expect(r.data['tickets'], isA<List>());
|
||||
});
|
||||
@@ -212,11 +203,7 @@ void main() {
|
||||
final missing = await call('pql.tickets.show');
|
||||
expect(missing.ok, isFalse);
|
||||
expect(missing.error!.kind, 'user_error');
|
||||
final ok = await call('pql.tickets.show', {
|
||||
'id': 'T-1',
|
||||
'withContext': true,
|
||||
'withBlockers': true,
|
||||
});
|
||||
final ok = await call('pql.tickets.show', {'id': 'T-1', 'withContext': true, 'withBlockers': true});
|
||||
expect(ok.ok, isTrue);
|
||||
});
|
||||
|
||||
|
||||
@@ -17,12 +17,7 @@ void main() {
|
||||
File('${dir.path}/a.dart').writeAsStringSync('final answer = 42;\n');
|
||||
File('${dir.path}/b.dart').writeAsStringSync('// no hits here\n');
|
||||
sink = RecordingEventSink();
|
||||
final service = SearchService(
|
||||
root: dir,
|
||||
ignore: IgnoreSet([]),
|
||||
events: sink,
|
||||
useIsolates: false,
|
||||
);
|
||||
final service = SearchService(root: dir, ignore: IgnoreSet([]), events: sink, useIsolates: false);
|
||||
d = DaemonDispatcher();
|
||||
registerSearchCommands(d, service);
|
||||
});
|
||||
|
||||
@@ -13,13 +13,7 @@ void main() {
|
||||
|
||||
test('status resolves and returns the assembled snapshot with exit 0', () async {
|
||||
final d = DaemonDispatcher();
|
||||
registerStatusCommand(
|
||||
d,
|
||||
() async => {
|
||||
'workspace': '/repo',
|
||||
'focusedFile': null,
|
||||
'panes': const [],
|
||||
});
|
||||
registerStatusCommand(d, () async => {'workspace': '/repo', 'focusedFile': null, 'panes': const []});
|
||||
final r = await d.dispatch(req());
|
||||
expect(r.ok, isTrue);
|
||||
expect(r.data['workspace'], '/repo');
|
||||
|
||||
@@ -20,19 +20,13 @@ void main() {
|
||||
published = [];
|
||||
filterValues = {};
|
||||
d = DaemonDispatcher();
|
||||
registerUiCommands(
|
||||
d,
|
||||
() {
|
||||
if (!liveUi) return null;
|
||||
return (publisher, channel, data) => published.add((publisher: publisher, channel: channel, data: data));
|
||||
},
|
||||
filterValue: liveUi ? (address) => filterValues[address] : null,
|
||||
);
|
||||
registerUiCommands(d, () {
|
||||
if (!liveUi) return null;
|
||||
return (publisher, channel, data) => published.add((publisher: publisher, channel: channel, data: data));
|
||||
}, filterValue: liveUi ? (address) => filterValues[address] : null);
|
||||
}
|
||||
|
||||
Future<IpcResponse> open(List<String> positional) => d.dispatch(
|
||||
IpcRequest(id: '1', cmd: 'ui.open', args: {'positional': positional}),
|
||||
);
|
||||
Future<IpcResponse> open(List<String> positional) => d.dispatch(IpcRequest(id: '1', cmd: 'ui.open', args: {'positional': positional}));
|
||||
|
||||
test('ui open tickets T-48 publishes a tickets selection', () async {
|
||||
wire();
|
||||
@@ -97,9 +91,8 @@ void main() {
|
||||
|
||||
// -- ui.toast (T-50 drive-half) -------------------------------------------
|
||||
|
||||
Future<IpcResponse> toast(List<String> positional, {Map<String, Object?>? flags}) => d.dispatch(
|
||||
IpcRequest(id: '1', cmd: 'ui.toast', args: {'positional': positional, if (flags != null) 'flags': flags}),
|
||||
);
|
||||
Future<IpcResponse> toast(List<String> positional, {Map<String, Object?>? flags}) =>
|
||||
d.dispatch(IpcRequest(id: '1', cmd: 'ui.toast', args: {'positional': positional, 'flags': ?flags}));
|
||||
|
||||
test('ui toast publishes a toast message (default info severity)', () async {
|
||||
wire();
|
||||
@@ -150,9 +143,7 @@ void main() {
|
||||
|
||||
// -- ui.filter (T-270 drive+observe half) ---------------------------------
|
||||
|
||||
Future<IpcResponse> filter(List<String> positional) => d.dispatch(
|
||||
IpcRequest(id: '1', cmd: 'ui.filter', args: {'positional': positional}),
|
||||
);
|
||||
Future<IpcResponse> filter(List<String> positional) => d.dispatch(IpcRequest(id: '1', cmd: 'ui.filter', args: {'positional': positional}));
|
||||
|
||||
test('ui filter <address> <text> publishes a filter.set', () async {
|
||||
wire();
|
||||
|
||||
Reference in New Issue
Block a user