Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ A unified command-line compression utility written in Rust, providing a consiste

## Features

- **Multi-Format Support**: GZIP, BZIP2, XZ, TAR, and compound formats (TGZ, TBZ2, TXZ)
- **Multi-Format Support**: GZIP, BZIP2, XZ, ZIP, TAR, and compound formats (TGZ, TBZ2, TXZ)
- **Parallel Processing**: Concurrent compression/decompression of multiple files using Rayon
- **Timestamp Options**: Add timestamps to output filenames (date, datetime, or nanoseconds)
- **File Collection**: Combine multiple files into single archives
Expand Down Expand Up @@ -32,6 +32,9 @@ jcz -c gzip file.txt
# Compress with BZIP2 at level 9
jcz -c bzip2 -l 9 file.txt

# Compress with ZIP
jcz -c zip file.txt

# Create TAR archive
jcz -c tar directory/
```
Expand Down Expand Up @@ -95,6 +98,7 @@ jcz -c tgz -A myarchive file1.txt file2.txt
- `gzip` - GZIP compression (.gz)
- `bzip2` - BZIP2 compression (.bz2)
- `xz` - XZ compression (.xz)
- `zip` - ZIP compression (.zip)
- `tar` - TAR archive (.tar)
- `tgz` - TAR + GZIP (.tar.gz)
- `tbz2` - TAR + BZIP2 (.tar.bz2)
Expand All @@ -117,7 +121,7 @@ JCDBG=debug jcz -c gzip file.txt
The implementation follows a modular design:

- **Core Module**: Trait definitions, error types, configuration structures
- **Compressor Modules**: Individual implementations for GZIP, BZIP2, XZ, TAR
- **Compressor Modules**: Individual implementations for GZIP, BZIP2, XZ, ZIP, TAR
- **Operations Module**: High-level operations (compress, decompress, compound, collection)
- **Utils Module**: File system utilities, logging, validation, timestamp generation
- **CLI Module**: Command-line argument parsing and command execution
Expand All @@ -140,7 +144,7 @@ The implementation follows a modular design:
## System Requirements

- Rust 2021 edition or later
- System utilities: `gzip`, `bzip2`, `xz`, `tar`, `mv`, `cp`, `readlink`
- System utilities: `gzip`, `bzip2`, `xz`, `zip`, `unzip`, `tar`, `mv`, `cp`, `readlink`

## Documentation

Expand Down
59 changes: 45 additions & 14 deletions docs/jcz_sdd.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Software Design Document (SDD)
## JCZ - Just Compress Zip Utility (Rust Implementation)

**Version:** 1.0
**Date:** 2025-11-01
**Version:** 1.1
**Date:** 2025-11-30
**Document Status:** Final
**Implementation Language:** Rust

Expand Down Expand Up @@ -69,14 +69,14 @@ This document covers:
│ (Trait Definitions, Common Interfaces, Type Dispatch) │
└──────────────────────┬──────────────────────────────────────┘
┌─────────────┼─────────────┬────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ GZIP │ │ BZIP2 │ │ XZ │ │ TAR │
│ Module │ │ Module │ │ Module │ │ Module │
└────────┘ └────────┘ └────────┘ └────────┘
│ │ │ │
└─────────────┴─────────────┴────────────┘
┌─────────────┼─────────────┬────────────┬────────────
▼ ▼ ▼ ▼
┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ GZIP │ │ BZIP2 │ │ XZ │ │ ZIP │ │ TAR │
│ Module │ │ Module │ │ Module │ │ Module │ │ Module │
└────────┘ └────────┘ └────────┘ └────────┘ └────────┘
│ │ │ │
└─────────────┴─────────────┴────────────┴────────────
┌─────────────────────────────────────────────────────────────┐
Expand Down Expand Up @@ -113,6 +113,7 @@ jcz/
│ │ ├── gzip.rs # GZIP implementation
│ │ ├── bzip2.rs # BZIP2 implementation
│ │ ├── xz.rs # XZ implementation
│ │ ├── zip.rs # ZIP implementation
│ │ └── tar.rs # TAR implementation
│ ├── operations/
│ │ ├── mod.rs # Operations module root
Expand Down Expand Up @@ -465,6 +466,7 @@ pub enum CompressionFormat {
Gzip,
Bzip2,
Xz,
Zip,
Tar,
}

Expand All @@ -475,6 +477,7 @@ impl CompressionFormat {
CompressionFormat::Gzip => "gz",
CompressionFormat::Bzip2 => "bz2",
CompressionFormat::Xz => "xz",
CompressionFormat::Zip => "zip",
CompressionFormat::Tar => "tar",
}
}
Expand All @@ -485,6 +488,7 @@ impl CompressionFormat {
"gz" => Some(CompressionFormat::Gzip),
"bz2" => Some(CompressionFormat::Bzip2),
"xz" => Some(CompressionFormat::Xz),
"zip" => Some(CompressionFormat::Zip),
"tar" => Some(CompressionFormat::Tar),
_ => None,
}
Expand All @@ -496,6 +500,7 @@ impl CompressionFormat {
CompressionFormat::Gzip => "gzip",
CompressionFormat::Bzip2 => "bzip2",
CompressionFormat::Xz => "xz",
CompressionFormat::Zip => "zip",
CompressionFormat::Tar => "tar",
}
}
Expand Down Expand Up @@ -954,12 +959,37 @@ impl MultiFileCompressor for TarCompressor {
- **Path manipulation**: Handle parent/basename splitting
- **No compression level**: Returns true for any level (no-op)

#### 3.2.3 Compressor Factory (`src/compressors/mod.rs`)
#### 3.2.3 ZIP Implementation (`src/compressors/zip.rs`)

**Purpose**: ZIP compression and decompression using system `zip` and `unzip` commands.

**Key Features**:
- Supports both files and directories
- Archive format (can contain multiple files)
- Compression levels 0-9
- Cross-platform compatibility

**Design Rationale**:
- **Archive support**: Unlike gzip/bzip2/xz, ZIP is both a compression algorithm and archive format
- **Directory compression**: Recursive flag (`-r`) enables directory compression
- **Quiet mode**: Suppress verbose output for cleaner logs
- **Flexible extraction**: Handles single files, directories, and multiple loose files

**Implementation Notes**:
- Uses `zip` command for compression with `-q` (quiet) and optional `-r` (recursive)
- Uses `unzip` command for decompression with `-o` (overwrite)
- Compression levels: 0 (store only) to 9 (maximum compression)
- Default level: 6
- Supports timestamp options for output naming
- `decompress_in_dir` method detects extraction result (single file, directory, or multiple files)

#### 3.2.4 Compressor Factory (`src/compressors/mod.rs`)

```rust
pub mod gzip;
pub mod bzip2;
pub mod xz;
pub mod zip;
pub mod tar;

use crate::core::compressor::Compressor;
Expand All @@ -972,6 +1002,7 @@ pub fn create_compressor(format: CompressionFormat) -> Box<dyn Compressor> {
CompressionFormat::Gzip => Box::new(gzip::GzipCompressor::new()),
CompressionFormat::Bzip2 => Box::new(bzip2::Bzip2Compressor::new()),
CompressionFormat::Xz => Box::new(xz::XzCompressor::new()),
CompressionFormat::Zip => Box::new(zip::ZipCompressor::new()),
CompressionFormat::Tar => Box::new(tar::TarCompressor::new()),
}
}
Expand Down Expand Up @@ -1929,7 +1960,7 @@ impl CliArgs {
}

// Validate compression command
let valid_commands = ["gzip", "bzip2", "xz", "tar", "tgz", "tbz2", "txz"];
let valid_commands = ["gzip", "bzip2", "xz", "zip", "tar", "tgz", "tbz2", "txz"];
if !valid_commands.contains(&self.command.as_str()) {
return Err(format!("Invalid compression command: {}", self.command));
}
Expand Down Expand Up @@ -2049,7 +2080,7 @@ fn handle_compress(
Ok(())
}
} else {
// Simple format (gzip, bzip2, xz, tar)
// Simple format (gzip, bzip2, xz, zip, tar)
let format = CompressionFormat::from_extension(command)
.ok_or_else(|| JcError::InvalidCommand(command.to_string()))?;

Expand Down Expand Up @@ -2336,7 +2367,7 @@ jobs:
- name: Install compression tools
run: |
sudo apt-get update
sudo apt-get install -y gzip bzip2 xz-utils tar
sudo apt-get install -y gzip bzip2 xz-utils zip unzip tar

- name: Check formatting
run: cargo fmt -- --check
Expand Down
68 changes: 57 additions & 11 deletions docs/jcz_srs.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Software Requirements Specification (SRS)
## JCZ - Just Compress Zip Utility

**Version:** 1.0
**Date:** 2025-11-01
**Version:** 1.1
**Date:** 2025-11-30
**Document Status:** Final

---
Expand All @@ -13,7 +13,7 @@
This document specifies the functional and non-functional requirements for JCZ (Just Compress Zip), a command-line compression utility that provides a unified interface for multiple compression formats.

### 1.2 Scope
JCZ is a command-line tool that simplifies file and directory compression/decompression operations. It supports multiple compression algorithms (GZIP, BZIP2, XZ) and archive formats (TAR), including compound formats (TAR+GZIP, TAR+BZIP2, TAR+XZ).
JCZ is a command-line tool that simplifies file and directory compression/decompression operations. It supports multiple compression algorithms (GZIP, BZIP2, XZ, ZIP) and archive formats (TAR), including compound formats (TAR+GZIP, TAR+BZIP2, TAR+XZ).

### 1.3 Intended Audience
- Software developers implementing the tool
Expand All @@ -27,6 +27,7 @@ JCZ is a command-line tool that simplifies file and directory compression/decomp
- **GZIP**: GNU Zip compression algorithm
- **BZIP2**: Burrows-Wheeler compression algorithm
- **XZ**: LZMA/LZMA2 compression algorithm
- **ZIP**: ZIP compression and archive format
- **TAR**: Tape Archive format
- **TGZ**: TAR + GZIP compound format (.tar.gz)
- **TBZ2**: TAR + BZIP2 compound format (.tar.bz2)
Expand All @@ -37,10 +38,10 @@ JCZ is a command-line tool that simplifies file and directory compression/decomp
## 2. Overall Description

### 2.1 Product Perspective
JCZ is a standalone command-line utility that wraps system compression tools (gzip, bzip2, xz, tar) to provide a consistent, simplified interface. It acts as a compression abstraction layer, allowing users to compress/decompress files without memorizing different command syntaxes for each compression tool.
JCZ is a standalone command-line utility that wraps system compression tools (gzip, bzip2, xz, zip, unzip, tar) to provide a consistent, simplified interface. It acts as a compression abstraction layer, allowing users to compress/decompress files without memorizing different command syntaxes for each compression tool.

### 2.2 Product Features
1. **Multi-Format Compression**: Support for GZIP, BZIP2, XZ, TAR, TGZ, TBZ2, TXZ
1. **Multi-Format Compression**: Support for GZIP, BZIP2, XZ, ZIP, TAR, TGZ, TBZ2, TXZ
2. **Multi-Format Decompression**: Automatic format detection and sequential decompression
3. **Isolated Decompression**: Temporary directory isolation prevents file conflicts
4. **Force Overwrite**: Skip interactive prompts with --force/-f flag
Expand All @@ -62,12 +63,12 @@ JCZ is a standalone command-line utility that wraps system compression tools (gz

### 2.4 Operating Environment
- **Operating Systems**: Linux, Unix-like systems
- **Dependencies**: System utilities (gzip, bzip2, xz, tar, mv, cp, readlink)
- **Dependencies**: System utilities (gzip, bzip2, xz, zip, unzip, tar, mv, cp, readlink)
- **Interface**: Command-line terminal
- **File Systems**: Any POSIX-compatible filesystem

### 2.5 Design and Implementation Constraints
1. Must use external system compression tools (gzip, bzip2, xz, tar)
1. Must use external system compression tools (gzip, bzip2, xz, zip, unzip, tar)
2. Must preserve original files during compression operations
3. Must handle file paths up to system limits
4. Must operate within terminal environment constraints
Expand All @@ -82,11 +83,11 @@ JCZ is a standalone command-line utility that wraps system compression tools (gz
#### 3.1.1 Compression Operations

##### FR-COMP-001: Single File Compression
**Description**: The system shall compress individual files using GZIP, BZIP2, or XZ algorithms.
**Description**: The system shall compress individual files using GZIP, BZIP2, XZ, or ZIP algorithms.

**Inputs**:
- Input file path (file or directory for TAR)
- Compression algorithm (gzip, bzip2, xz, tar)
- Input file path (file or directory for TAR/ZIP)
- Compression algorithm (gzip, bzip2, xz, zip, tar)
- Optional: Compression level (1-9)
- Optional: Timestamp option (0-3)
- Optional: Destination directory
Expand Down Expand Up @@ -435,6 +436,7 @@ JCZ is a standalone command-line utility that wraps system compression tools (gz
- `gzip`
- `bzip2`
- `xz`
- `zip`
- `tar`
- `tgz`
- `tbz2`
Expand All @@ -451,6 +453,7 @@ JCZ is a standalone command-line utility that wraps system compression tools (gz
- `.gz`
- `.bz2`
- `.xz`
- `.zip`
- `.tar`
- `.tar.gz`
- `.tar.bz2`
Expand Down Expand Up @@ -541,6 +544,8 @@ jcz [Options] <File|Dir> [File|Dir]...
- `gzip`: For GZIP compression/decompression
- `bzip2`: For BZIP2 compression/decompression
- `xz`: For XZ compression/decompression
- `zip`: For ZIP compression
- `unzip`: For ZIP decompression
- `tar`: For TAR archive creation/extraction
- `mv`: For moving files
- `cp`: For copying files
Expand Down Expand Up @@ -912,7 +917,48 @@ jcz [Options] <File|Dir> [File|Dir]...
- Cannot compress directories (must error)
- Only compresses single files

#### 4.5.4 TAR Archiving
#### 4.5.4 ZIP Compression

**Algorithm**: DEFLATE (similar to GZIP) with archive support

**Extension**: `.zip`

**Compression Tool**: `zip` (compression), `unzip` (decompression)

**Tool Arguments**:
- Compression: `zip -<level> -q [-r] <outfile> <infile>`
- Decompression: `unzip -o <infile> -d <outdir>`

**Compression Levels**: 0-9
- 0: Store only (no compression)
- 1: Fastest compression
- 9: Best compression
- Default: 6

**Default Behavior**:
- Keep original file (zip doesn't modify source)
- Recursive flag (`-r`) for directories
- Quiet mode (`-q`) to suppress output
- Overwrite without prompting (`-o`) for decompression

**File Naming**:
- Without timestamp: `<filename>.zip`
- With timestamp: `<filename>_<timestamp>.zip`

**Decompression**:
- Extract to parent directory or specified destination
- Remove `.zip` extension to determine output name
- Supports single files, directories, and multiple files

**Special Features**:
- Can compress both files and directories
- Archive format (can contain multiple files)
- Cross-platform compatibility

**Restrictions**:
- None (supports both files and directories)

#### 4.5.5 TAR Archiving

**Format**: POSIX ustar format

Expand Down
2 changes: 1 addition & 1 deletion src/cli/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl CliArgs {
}

// Validate compression command
let valid_commands = ["gzip", "bzip2", "xz", "tar", "tgz", "tbz2", "txz"];
let valid_commands = ["gzip", "bzip2", "xz", "tar", "zip", "tgz", "tbz2", "txz"];
if !valid_commands.contains(&self.command.as_str()) {
return Err(format!("Invalid compression command: {}", self.command));
}
Expand Down
3 changes: 3 additions & 0 deletions src/compressors/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ pub mod bzip2;
pub mod gzip;
pub mod tar;
pub mod xz;
pub mod zip;

use std::path::Path;

Expand All @@ -12,6 +13,7 @@ pub use bzip2::Bzip2Compressor;
pub use gzip::GzipCompressor;
pub use tar::TarCompressor;
pub use xz::XzCompressor;
pub use zip::ZipCompressor;

/// Create a compressor instance for the given format
pub fn create_compressor(format: CompressionFormat) -> Box<dyn Compressor> {
Expand All @@ -20,6 +22,7 @@ pub fn create_compressor(format: CompressionFormat) -> Box<dyn Compressor> {
CompressionFormat::Bzip2 => Box::new(bzip2::Bzip2Compressor::new()),
CompressionFormat::Xz => Box::new(xz::XzCompressor::new()),
CompressionFormat::Tar => Box::new(tar::TarCompressor::new()),
CompressionFormat::Zip => Box::new(zip::ZipCompressor::new()),
}
}

Expand Down
Loading