fix(cli,vault): polish init output and interactive set

This commit is contained in:
Chris Hendrickson 2026-05-03 13:52:08 -04:00
parent bd40758bb2
commit 0cd08e78d3
6 changed files with 46 additions and 8 deletions

8
.gitignore vendored
View file

@ -1,6 +1,4 @@
# https://dart.dev/guides/libraries/private-files # Dew Git Ignore
# Created by `dart pub`
.dart_tool/
# Compiled toolchain binaries ## Dart
.project/toolchain/ .dart_tool/

3
.project/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
/cache/
/secrets/
/toolchain/

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:args/command_runner.dart'; import 'package:args/command_runner.dart';
import 'package:dew_core/dew_core.dart'; import 'package:dew_core/dew_core.dart';
import 'package:dew_kanban/dew_kanban.dart' as kanban; import 'package:dew_kanban/dew_kanban.dart' as kanban;
@ -18,5 +20,10 @@ Future<void> main(List<String> args) async {
runner.addCommand(command); runner.addCommand(command);
} }
try {
await runner.run(args); await runner.run(args);
} on UsageException catch (error) {
stderr.writeln(error);
exitCode = 64;
}
} }

View file

@ -60,6 +60,12 @@ dew:
color: "green" color: "green"
'''; ''';
const _projectGitignore = '''
/secrets/
/toolchain/
/cache/
''';
class InitCommand extends Command<void> { class InitCommand extends Command<void> {
final List<DewInitHook> _hooks; final List<DewInitHook> _hooks;
final FileSystem _fs; final FileSystem _fs;
@ -97,6 +103,7 @@ class InitCommand extends Command<void> {
final projectDir = _fs.directory(p.join(projectRoot, '.project')); final projectDir = _fs.directory(p.join(projectRoot, '.project'));
final configFile = _fs.file(p.join(projectDir.path, 'dew.yaml')); final configFile = _fs.file(p.join(projectDir.path, 'dew.yaml'));
final gitignoreFile = _fs.file(p.join(projectDir.path, '.gitignore'));
await projectDir.create(recursive: true); await projectDir.create(recursive: true);
@ -107,6 +114,13 @@ class InitCommand extends Command<void> {
print(' created .project/dew.yaml'); print(' created .project/dew.yaml');
} }
if (await gitignoreFile.exists()) {
print(' found .project/.gitignore (already exists, skipping)');
} else {
await gitignoreFile.writeAsString(_projectGitignore);
print(' created .project/.gitignore');
}
final config = DewConfig.fromYaml( final config = DewConfig.fromYaml(
loadYaml(await configFile.readAsString()) as YamlMap, loadYaml(await configFile.readAsString()) as YamlMap,
); );

View file

@ -42,6 +42,7 @@ Future<String?> readSecretInput(
required FileSystem fs, required FileSystem fs,
bool required = true, bool required = true,
bool allowStdin = true, bool allowStdin = true,
String? prompt,
String? projectRoot, String? projectRoot,
}) async { }) async {
final envVar = args['env']?.toString(); final envVar = args['env']?.toString();
@ -67,11 +68,25 @@ Future<String?> readSecretInput(
return value.trimRight(); return value.trimRight();
} }
if (!allowStdin || stdin.hasTerminal) { if (!allowStdin) {
if (!required) return null; if (!required) return null;
throw ArgumentError('Missing secret value. Use --env, --file, or pipe input.'); throw ArgumentError('Missing secret value. Use --env, --file, or pipe input.');
} }
if (stdin.hasTerminal) {
if (prompt != null) {
stdout.write('$prompt: ');
}
final input = stdin.readLineSync();
if (input == null || input.trim().isEmpty) {
if (!required) return null;
throw ArgumentError(
'Missing secret value. Use --env, --file, or pipe input.',
);
}
return input.trimRight();
}
final input = (await stdin.transform(utf8.decoder).join()).trimRight(); final input = (await stdin.transform(utf8.decoder).join()).trimRight();
if (input.trim().isEmpty) { if (input.trim().isEmpty) {
if (!required) return null; if (!required) return null;

View file

@ -61,7 +61,8 @@ class SetCommand extends DewCommand with DewToolCommand {
fs: context.fs, fs: context.fs,
projectRoot: context.root, projectRoot: context.root,
required: true, required: true,
allowStdin: false, allowStdin: true,
prompt: 'Enter value for secret "$secretName"',
); );
await store.write(secretName, value!, metadata: metadata); await store.write(secretName, value!, metadata: metadata);