Skip to content

Commit

Permalink
_cli: implement --output-directory (#627)
Browse files Browse the repository at this point in the history
* _cli: implement `--output-directory`

Signed-off-by: Andrew Pan <a@tny.town>

* CHANGELOG: doc

Signed-off-by: Andrew Pan <a@tny.town>

* CHANGELOG: backfill link for 525

Signed-off-by: Andrew Pan <a@tny.town>

* _cli: create output directory if it does not exist

Signed-off-by: Andrew Pan <a@tny.town>

* README: update `sigstore sign` helptext

Signed-off-by: Andrew Pan <a@tny.town>

* _cli: reformat

Signed-off-by: Andrew Pan <a@tny.town>

* README: `--output-directory` in arg list

Signed-off-by: Andrew Pan <a@tny.town>

---------

Signed-off-by: Andrew Pan <a@tny.town>
Co-authored-by: William Woodruff <william@trailofbits.com>
  • Loading branch information
tnytown and woodruffw authored Apr 25, 2023
1 parent e93d5e9 commit 5806c16
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ All versions prior to 0.9.0 are untracked.

### Added

* `sigstore sign` now supports the `--output-directory` flag, which places
default outputs in the specified directory. Without this flag, default outputs
are placed adjacent to the signing input.
([#627](https://github.com/sigstore/sigstore-python/pull/627))

* The whole test suite can now be run locally with `make test-interactive`.
([#576](https://github.com/sigstore/sigstore-python/pull/576))
Users will be prompted to authenticate with their identity provider twice to
Expand All @@ -44,6 +49,7 @@ All versions prior to 0.9.0 are untracked.

* Network-related errors from the `sigstore._internal.tuf` module now have better
diagnostics.
([#525](https://github.com/sigstore/sigstore-python/pull/525))

### Changed

Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,9 @@ usage: sigstore sign [-h] [--identity-token TOKEN] [--oidc-client-id ID]
[--oidc-client-secret SECRET]
[--oidc-disable-ambient-providers] [--oidc-issuer URL]
[--no-default-files] [--signature FILE]
[--certificate FILE] [--bundle FILE] [--overwrite]
[--staging] [--rekor-url URL] [--rekor-root-pubkey FILE]
[--certificate FILE] [--bundle FILE]
[--output-directory DIR] [--overwrite] [--staging]
[--rekor-url URL] [--rekor-root-pubkey FILE]
[--fulcio-url URL] [--ctfe FILE]
FILE [FILE ...]

Expand Down Expand Up @@ -167,6 +168,10 @@ Output options:
work with multiple input files (default: None)
--bundle FILE Write a single Sigstore bundle to the given file; does
not work with multiple input files (default: None)
--output-directory DIR
Write default outputs to the given directory
(conflicts with --signature, --certificate, --bundle)
(default: None)
--overwrite Overwrite preexisting signature and certificate
outputs, if present (default: False)

Expand Down
25 changes: 24 additions & 1 deletion sigstore/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,16 @@ def _parser() -> argparse.ArgumentParser:
"files"
),
)
output_options.add_argument(
"--output-directory",
metavar="DIR",
type=Path,
default=os.getenv("SIGSTORE_OUTPUT_DIRECTORY"),
help=(
"Write default outputs to the given directory (conflicts with --signature, --certificate"
", --bundle)"
),
)
output_options.add_argument(
"--overwrite",
action="store_true",
Expand Down Expand Up @@ -571,6 +581,12 @@ def _sign(args: argparse.Namespace) -> None:
"explicit outputs for multiple inputs.",
)

if args.output_directory and (has_sig or has_crt or has_bundle):
args._parser.error(
"Error: --signature, --certificate, and --bundle can't be used with "
"an explicit output directory.",
)

# Fail if either `--signature` or `--certificate` is specified, but not both.
if has_sig ^ has_crt:
args._parser.error(
Expand All @@ -590,8 +606,15 @@ def _sign(args: argparse.Namespace) -> None:
args.bundle,
)

output_dir = args.output_directory if args.output_directory else file.parent
if output_dir.exists() and not output_dir.is_dir():
args._parser.error(
f"Output directory exists and is not a directory: {output_dir}"
)
output_dir.mkdir(parents=True, exist_ok=True)

if not bundle and not args.no_default_files:
bundle = file.parent / f"{file.name}.sigstore"
bundle = output_dir / f"{file.name}.sigstore"

if not args.overwrite:
extants = []
Expand Down

0 comments on commit 5806c16

Please sign in to comment.