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
# Created by `dart pub`
.dart_tool/
# Dew Git Ignore
# Compiled toolchain binaries
.project/toolchain/
## Dart
.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:dew_core/dew_core.dart';
import 'package:dew_kanban/dew_kanban.dart' as kanban;
@ -18,5 +20,10 @@ Future<void> main(List<String> args) async {
runner.addCommand(command);
}
await runner.run(args);
try {
await runner.run(args);
} on UsageException catch (error) {
stderr.writeln(error);
exitCode = 64;
}
}

View file

@ -60,6 +60,12 @@ dew:
color: "green"
''';
const _projectGitignore = '''
/secrets/
/toolchain/
/cache/
''';
class InitCommand extends Command<void> {
final List<DewInitHook> _hooks;
final FileSystem _fs;
@ -97,6 +103,7 @@ class InitCommand extends Command<void> {
final projectDir = _fs.directory(p.join(projectRoot, '.project'));
final configFile = _fs.file(p.join(projectDir.path, 'dew.yaml'));
final gitignoreFile = _fs.file(p.join(projectDir.path, '.gitignore'));
await projectDir.create(recursive: true);
@ -107,6 +114,13 @@ class InitCommand extends Command<void> {
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(
loadYaml(await configFile.readAsString()) as YamlMap,
);

View file

@ -42,6 +42,7 @@ Future<String?> readSecretInput(
required FileSystem fs,
bool required = true,
bool allowStdin = true,
String? prompt,
String? projectRoot,
}) async {
final envVar = args['env']?.toString();
@ -67,11 +68,25 @@ Future<String?> readSecretInput(
return value.trimRight();
}
if (!allowStdin || stdin.hasTerminal) {
if (!allowStdin) {
if (!required) return null;
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();
if (input.trim().isEmpty) {
if (!required) return null;

View file

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