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
27 changes: 18 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,17 @@ ghr [OPTIONS] --repo <REPO>
| Clone | `-c` | `--clone <URL[:REF]>` | Clone repository with optional branch/tag/commit |
| Download | `-d` | `--download <VERSION>` | Download specific version (or "latest") |
| Filter | `-f` | `--filter <FILTERS>` | Filter assets by comma-separated patterns |
| Output Dir | `-o` | `--output-dir <PATH>` | Save downloads to specified directory |
| Info | `-i` | `--info <VERSIONS>` | Show info about specific versions (comma-separated) |
| Number | `-n` | `--num <NUM>` | Number of releases to list (default: 1) |
| Concurrency | `-j` | `--concurrency <NUM>` | Maximum number of concurrent downloads (default: 5) |
| Verbose | `-v` | `--verbose` | Increase verbosity (-v, -vv for more detail) |

### Positional Arguments

| Argument | Description |
|----------|-------------|
| `[DIRECTORY]` | Directory for downloads or clone destination |

## Examples

### List Latest Release
Expand All @@ -72,17 +77,21 @@ ghr -r owner/repo -n 5
### Download Latest Release

```bash
# Download all assets from latest release
# Download all assets from latest release to current directory
ghr -r owner/repo -d latest

# Download to specific directory
ghr -r owner/repo -d latest -o ./downloads
ghr -r owner/repo -d latest ./downloads
```

### Download Specific Version

```bash
# Download to current directory
ghr -r owner/repo -d v1.2.3

# Download to specific directory
ghr -r owner/repo -d v1.2.3 ./releases
```

### Download with Filtering
Expand Down Expand Up @@ -197,21 +206,21 @@ ghr -r owner/private-repo -d latest
```yaml
- name: Download release asset
run: |
ghr -r owner/repo -d latest -f "linux,amd64" -o ./bin
ghr -r owner/repo -d latest -f "linux,amd64" ./bin
```

#### GitLab CI

```yaml
download_release:
script:
- ghr -r owner/repo -d v1.0.0 -t $GITHUB_TOKEN -o ./artifacts
- ghr -r owner/repo -d v1.0.0 -t $GITHUB_TOKEN ./artifacts
```

#### Jenkins

```groovy
sh 'ghr -r owner/repo -d latest -T /var/jenkins/.github_token'
sh 'ghr -r owner/repo -d latest -T /var/jenkins/.github_token ./bin'
```

## Authentication
Expand Down Expand Up @@ -290,7 +299,7 @@ ghr -r owner/repo -d latest -vv

```bash
#!/bin/bash
ghr -r mycompany/app -d latest -f "linux,amd64" -o /tmp
ghr -r mycompany/app -d latest -f "linux,amd64" /tmp
sudo dpkg -i /tmp/app_*_amd64.deb
```

Expand All @@ -299,7 +308,7 @@ sudo dpkg -i /tmp/app_*_amd64.deb
```bash
#!/bin/bash
for platform in linux darwin windows; do
ghr -r owner/repo -d v1.0.0 -f "$platform" -o "./dist/$platform"
ghr -r owner/repo -d v1.0.0 -f "$platform" "./dist/$platform"
done
```

Expand All @@ -312,7 +321,7 @@ latest=$(ghr -r owner/repo -n 1 2>&1 | grep "Tag:" | awk '{print $2}')

if [ "$latest" != "$current_version" ]; then
echo "New version available: $latest"
ghr -r owner/repo -d latest -o ./updates
ghr -r owner/repo -d latest ./updates
fi
```

Expand Down
11 changes: 4 additions & 7 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use clap::{ArgAction, Parser};
use std::path::PathBuf;

/// CLI arguments
#[derive(Parser)]
Expand Down Expand Up @@ -37,10 +36,6 @@ pub struct Cli {
#[arg(short = 's', long = "search")]
pub search: Option<String>,

/// Directory to save downloaded assets (defaults to current directory)
#[arg(short = 'o', long = "output-dir")]
pub output_dir: Option<PathBuf>,

/// Show information about a specific version, multiple versions can be separated by commas.
#[arg(short = 'i', long = "info")]
pub info: Option<String>,
Expand All @@ -61,8 +56,10 @@ pub struct Cli {
#[arg(short = 'c', long = "clone", value_name = "URL[:REF]")]
pub clone: Option<String>,

/// Local directory for cloned repository (defaults to repository name)
#[arg(value_name = "DIRECTORY", requires = "clone")]
/// Directory for operation (clone destination or download location)
/// - For clone: defaults to repository name
/// - For download: defaults to current directory
#[arg(value_name = "DIRECTORY")]
pub directory: Option<String>,

#[arg(short = 'v', long = "verbose", action = ArgAction::Count)]
Expand Down
17 changes: 6 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,15 +158,10 @@ async fn main() -> Result<()> {
};

// Create output directory if specified
if let Some(output_dir) = &cli.output_dir {
fs::create_dir_all(output_dir).map_err(|e| {
format!(
"Failed to create output directory '{}': {}",
output_dir.display(),
e
)
})?;
jinfo!("Saving assets to: {}", output_dir.display());
if let Some(directory) = &cli.directory {
fs::create_dir_all(directory)
.map_err(|e| format!("Failed to create output directory '{}': {}", directory, e))?;
jinfo!("Saving assets to: {}", directory);
}

// Collect assets to download with filtering
Expand Down Expand Up @@ -197,8 +192,8 @@ async fn main() -> Result<()> {
let size = asset.size;

// Construct output path
let output_path = if let Some(output_dir) = &cli.output_dir {
output_dir.join(name)
let output_path = if let Some(directory) = &cli.directory {
PathBuf::from(directory).join(name)
} else {
PathBuf::from(name)
};
Expand Down
Loading