diff --git a/README.md b/README.md index bd0782d..147c7fa 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,7 @@ Enter passphrase: ***** | Option | Description | | --- | --- | +| `--comment` | Archive comment. | | `--compression`, `-c` | Compression for all files: `bz2` or `none` (Default: `bz2`) | | `--mode` | Store file/directory modes. | | `--mtime` | Store file/directory modification times. | diff --git a/src/icepack/__init__.py b/src/icepack/__init__.py index 0b4ec4f..20d9688 100644 --- a/src/icepack/__init__.py +++ b/src/icepack/__init__.py @@ -151,6 +151,7 @@ def __init__( self, archive_path, key_path, + comment=None, compression=Compression.BZ2, mode=False, mtime=False, @@ -161,6 +162,7 @@ def __init__( self._zipfile = Zip(self.archive_path, mode='w') self.metadata = Metadata( archive_name=self.archive_path.name, + comment=comment, checksum_type=Checksum.SHA256, encryption=Encryption.AGE, encryption_key=Age.keygen()[0]) @@ -252,6 +254,7 @@ def create_archive( src_path, dst_path, key_path, + comment=None, compression=Compression.BZ2, mode=False, mtime=False, @@ -280,6 +283,7 @@ def create_archive( if not r.startswith('ssh-'): raise Exception(f'Invalid recipient: {r}') kwargs = { + 'comment': comment, 'compression': compression, 'mode': mode, 'mtime': mtime, @@ -309,6 +313,8 @@ def extract_archive( 'mtime': mtime, } with IcepackReader(src_path, key_path, **kwargs) as archive: + if archive.metadata.comment: + log(f'Comment: {archive.metadata.comment}') for entry in archive.metadata.entries: log(entry.name) archive.extract_entry(entry, dst_path) diff --git a/src/icepack/cli.py b/src/icepack/cli.py index 2687908..49c9087 100644 --- a/src/icepack/cli.py +++ b/src/icepack/cli.py @@ -44,6 +44,7 @@ def init(ctx): @icepack.command() @click.argument('src', type=click.Path(exists=True)) @click.argument('dst', type=click.Path()) +@click.option('--comment', help='Archive comment.') @click.option( '--compression', '-c', help='Compression for all files.', @@ -62,7 +63,7 @@ def init(ctx): help='Allow another public key/alias to extract.', multiple=True) @click.pass_context -def create(ctx, src, dst, compression, mode, mtime, recipient): +def create(ctx, src, dst, comment, compression, mode, mtime, recipient): """Store files in an archive. SRC must be a file or directory, DST must be the archive file. @@ -76,6 +77,7 @@ def create(ctx, src, dst, compression, mode, mtime, recipient): src_path, dst_path, key_path, + comment=comment, compression=compression, mode=mode, mtime=mtime, @@ -128,6 +130,8 @@ def list_archive(ctx, src): _check_keys(key_path) try: with IcepackReader(src_path, key_path) as archive: + if archive.metadata.comment: + click.echo(f'Comment: {archive.metadata.comment}') for entry in archive.metadata.entries: click.echo(entry.name) except Exception as e: diff --git a/src/icepack/model.py b/src/icepack/model.py index b590f99..7ae5a5d 100644 --- a/src/icepack/model.py +++ b/src/icepack/model.py @@ -79,6 +79,7 @@ def is_dir(self): class Metadata(BaseModel): """Archive metadata.""" archive_name: str + comment: Optional[str] = None checksum_type: str encryption: str encryption_key: str diff --git a/tests/test_cli.py b/tests/test_cli.py index c6c8ab6..16d55c0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -54,6 +54,29 @@ def test_round_trip_file(src_path, dst_path, zip_path, key_path): compare_paths(file_path, dst_path / 'foo') +def test_comment(src_path, dst_path, zip_path, key_path): + """Test creation and extraction with --comment.""" + # Create archive + args = [ + '-c', str(key_path), + 'create', + str(src_path), + str(zip_path), + '--comment', 'Hello, World!' + ] + run_cli(args) + # Extract archive + args = [ + '-c', str(key_path), + 'extract', + str(zip_path), + str(dst_path) + ] + result = run_cli(args) + # Check for comment + assert 'Hello, World!' in result.stdout + + def test_none_compression(src_path, dst_path, zip_path, key_path): """Test round-trip with "none" compression.""" # Create archive