import 'dart:io'; import 'package:args/command_runner.dart'; import 'package:pipe/src/cli.dart'; import 'package:pipe/src/errors.dart'; /// Exit codes: /// /// - 0: success. /// - 1: a gate failed: `check --fail-on`, `verify --expect-resolved`, /// `recall --strict`, `index --fail-on-error`, or `guide --yams` could not /// persist. /// - 2: pipe could not do what was asked (a [PipeException], or a filesystem /// error such as an unreadable or unwritable path). /// - 64: invalid command-line usage. Future main(List arguments) async { final runner = PipeRunner(); try { exitCode = await runner.run(arguments) ?? 0; } on PipeException catch (error) { stderr.writeln(error); exitCode = 2; } on FileSystemException catch (error) { // Any filesystem failure not already turned into a PipeException still gets // a one-line message and a documented exit code, not a stack trace and 255. stderr.writeln( 'pipe: ${error.message}' '${error.path == null ? '' : ': ${error.path}'}' '${error.osError == null ? '' : ' (${error.osError!.message})'}', ); exitCode = 2; } on UsageException catch (error) { stderr.writeln(error.message); stderr.writeln(error.usage); exitCode = 64; } catch (error, stack) { // Anything else is a pipe bug. Say so in one line with the documented // "could not do what was asked" code instead of a raw trace and exit 255; // PIPE_DEBUG=1 restores the trace for a bug report. stderr.writeln('pipe: internal error: $error'); if (Platform.environment['PIPE_DEBUG'] == '1') { stderr.writeln(stack); } else { stderr.writeln('pipe: rerun with PIPE_DEBUG=1 for a stack trace'); } exitCode = 2; } }