|
1 | 1 | use std::path::PathBuf; |
2 | 2 |
|
3 | 3 | use clap::Parser; |
4 | | -use clap::Subcommand; |
5 | 4 |
|
6 | 5 | use appimageupdate::config; |
7 | 6 | use appimageupdate::{Error, Updater}; |
8 | 7 |
|
9 | 8 | #[derive(Parser)] |
10 | 9 | #[command(name = "appimageupdate")] |
11 | | -#[command(about = "Update AppImages using delta updates", long_about = None)] |
| 10 | +#[command(about = "AppImage companion tool taking care of updates for the commandline.", long_about = None)] |
12 | 11 | #[command(version)] |
13 | 12 | struct Cli { |
14 | | - #[command(subcommand)] |
15 | | - command: Commands, |
16 | | -} |
| 13 | + #[arg(value_name = "APPIMAGE")] |
| 14 | + path: Option<PathBuf>, |
17 | 15 |
|
18 | | -#[derive(Subcommand)] |
19 | | -enum Commands { |
20 | | - Update { |
21 | | - #[arg(value_name = "APPIMAGE")] |
22 | | - path: PathBuf, |
| 16 | + #[arg(short = 'O', long)] |
| 17 | + overwrite: bool, |
23 | 18 |
|
24 | | - #[arg(short, long)] |
25 | | - overwrite: bool, |
| 19 | + #[arg(short = 'r', long)] |
| 20 | + remove_old: bool, |
26 | 21 |
|
27 | | - #[arg(short, long, value_name = "DIR")] |
28 | | - output: Option<PathBuf>, |
| 22 | + #[arg(short = 'u', long, value_name = "INFO")] |
| 23 | + update_info: Option<String>, |
29 | 24 |
|
30 | | - #[arg(long, value_name = "URL", env = "GITHUB_API_PROXY")] |
31 | | - github_api_proxy: Option<String>, |
32 | | - }, |
| 25 | + #[arg(short = 'd', long)] |
| 26 | + describe: bool, |
33 | 27 |
|
34 | | - Check { |
35 | | - #[arg(value_name = "APPIMAGE")] |
36 | | - path: PathBuf, |
| 28 | + #[arg(short = 'j', long)] |
| 29 | + check_for_update: bool, |
37 | 30 |
|
38 | | - #[arg(long, value_name = "URL", env = "GITHUB_API_PROXY")] |
39 | | - github_api_proxy: Option<String>, |
40 | | - }, |
| 31 | + #[arg(long, value_name = "URL", env = "GITHUB_API_PROXY")] |
| 32 | + github_api_proxy: Option<String>, |
41 | 33 | } |
42 | 34 |
|
43 | 35 | fn main() { |
@@ -66,100 +58,90 @@ fn format_size(bytes: u64) -> String { |
66 | 58 | } |
67 | 59 |
|
68 | 60 | fn run(cli: Cli) -> Result<(), Error> { |
69 | | - match cli.command { |
70 | | - Commands::Update { |
71 | | - path, |
72 | | - overwrite, |
73 | | - output, |
74 | | - github_api_proxy, |
75 | | - } => { |
76 | | - config::init(github_api_proxy); |
| 61 | + config::init(cli.github_api_proxy); |
77 | 62 |
|
78 | | - let mut updater = Updater::new(&path)?; |
| 63 | + let path = cli.path.ok_or_else(|| { |
| 64 | + Error::AppImage("No AppImage path provided. Use --help for usage.".into()) |
| 65 | + })?; |
79 | 66 |
|
80 | | - if overwrite { |
81 | | - updater = updater.overwrite(true); |
82 | | - } |
| 67 | + let updater = if let Some(ref update_info) = cli.update_info { |
| 68 | + Updater::with_update_info(&path, update_info)? |
| 69 | + } else { |
| 70 | + Updater::new(&path)? |
| 71 | + }; |
83 | 72 |
|
84 | | - if let Some(dir) = output { |
85 | | - updater = updater.output_dir(dir); |
86 | | - } |
| 73 | + if cli.describe { |
| 74 | + let source_path = updater.source_path(); |
| 75 | + let source_size = updater.source_size(); |
| 76 | + let (target_path, target_size) = updater.target_info()?; |
87 | 77 |
|
88 | | - let source_path = updater.source_path(); |
89 | | - let source_size = updater.source_size(); |
90 | | - let (target_path, target_size) = updater.target_info()?; |
| 78 | + println!("Path: {}", source_path.display()); |
| 79 | + println!("Size: {}", format_size(source_size)); |
| 80 | + println!("Target: {}", target_path.display()); |
| 81 | + println!("Target Size: {}", format_size(target_size)); |
| 82 | + println!("Update Info: {}", updater.update_info()); |
91 | 83 |
|
92 | | - println!( |
93 | | - "Source: {} ({})", |
94 | | - source_path.display(), |
95 | | - format_size(source_size) |
96 | | - ); |
97 | | - println!( |
98 | | - "Target: {} ({})", |
99 | | - target_path.display(), |
100 | | - format_size(target_size) |
101 | | - ); |
102 | | - println!(); |
| 84 | + return Ok(()); |
| 85 | + } |
103 | 86 |
|
104 | | - if updater.check_for_update()? { |
105 | | - println!("Performing delta update..."); |
106 | | - let (new_path, stats) = updater.perform_update()?; |
107 | | - |
108 | | - if stats.blocks_reused > 0 || stats.blocks_downloaded > 0 { |
109 | | - println!(); |
110 | | - println!( |
111 | | - "Reused: {:>10} ({} blocks)", |
112 | | - format_size(stats.bytes_reused()), |
113 | | - stats.blocks_reused |
114 | | - ); |
115 | | - println!( |
116 | | - "Downloaded: {:>10} ({} blocks)", |
117 | | - format_size(stats.bytes_downloaded()), |
118 | | - stats.blocks_downloaded |
119 | | - ); |
120 | | - println!( |
121 | | - "Saved: {:>10} ({}%)", |
122 | | - format_size(stats.bytes_reused()), |
123 | | - stats.saved_percentage() |
124 | | - ); |
125 | | - } |
126 | | - |
127 | | - println!(); |
128 | | - println!("Updated: {}", new_path.display()); |
129 | | - } else { |
130 | | - println!("Already up to date!"); |
131 | | - } |
132 | | - } |
133 | | - Commands::Check { |
134 | | - path, |
135 | | - github_api_proxy, |
136 | | - } => { |
137 | | - config::init(github_api_proxy); |
| 87 | + if cli.check_for_update { |
| 88 | + let has_update = updater.check_for_update()?; |
| 89 | + std::process::exit(if has_update { 1 } else { 0 }); |
| 90 | + } |
138 | 91 |
|
139 | | - let updater = Updater::new(&path)?; |
| 92 | + let source_path = updater.source_path().to_path_buf(); |
| 93 | + let source_size = updater.source_size(); |
| 94 | + let (target_path, target_size) = updater.target_info()?; |
| 95 | + |
| 96 | + println!( |
| 97 | + "Source: {} ({})", |
| 98 | + source_path.display(), |
| 99 | + format_size(source_size) |
| 100 | + ); |
| 101 | + println!( |
| 102 | + "Target: {} ({})", |
| 103 | + target_path.display(), |
| 104 | + format_size(target_size) |
| 105 | + ); |
| 106 | + println!(); |
| 107 | + |
| 108 | + let mut updater = updater; |
| 109 | + if cli.overwrite { |
| 110 | + updater = updater.overwrite(true); |
| 111 | + } |
140 | 112 |
|
141 | | - let source_path = updater.source_path(); |
142 | | - let source_size = updater.source_size(); |
143 | | - let (target_path, target_size) = updater.target_info()?; |
| 113 | + if updater.check_for_update()? { |
| 114 | + println!("Performing delta update..."); |
| 115 | + let (new_path, stats) = updater.perform_update()?; |
144 | 116 |
|
| 117 | + if stats.blocks_reused > 0 || stats.blocks_downloaded > 0 { |
| 118 | + println!(); |
145 | 119 | println!( |
146 | | - "Source: {} ({})", |
147 | | - source_path.display(), |
148 | | - format_size(source_size) |
| 120 | + "Reused: {:>10} ({} blocks)", |
| 121 | + format_size(stats.bytes_reused()), |
| 122 | + stats.blocks_reused |
149 | 123 | ); |
150 | 124 | println!( |
151 | | - "Target: {} ({})", |
152 | | - target_path.display(), |
153 | | - format_size(target_size) |
| 125 | + "Downloaded: {:>10} ({} blocks)", |
| 126 | + format_size(stats.bytes_downloaded()), |
| 127 | + stats.blocks_downloaded |
154 | 128 | ); |
155 | | - println!(); |
| 129 | + println!( |
| 130 | + "Saved: {:>10} ({}%)", |
| 131 | + format_size(stats.bytes_reused()), |
| 132 | + stats.saved_percentage() |
| 133 | + ); |
| 134 | + } |
156 | 135 |
|
157 | | - if updater.check_for_update()? { |
158 | | - println!("Status: Update available"); |
159 | | - } else { |
160 | | - println!("Status: Up to date"); |
161 | | - } |
| 136 | + println!(); |
| 137 | + println!("Updated: {}", new_path.display()); |
| 138 | + |
| 139 | + if cli.remove_old && new_path != source_path { |
| 140 | + std::fs::remove_file(source_path)?; |
| 141 | + println!("Removed old AppImage"); |
162 | 142 | } |
| 143 | + } else { |
| 144 | + println!("Already up to date!"); |
163 | 145 | } |
164 | 146 |
|
165 | 147 | Ok(()) |
|
0 commit comments