@ahqstore/cli 0.3.4 → 0.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +10 -5
- package/index.js +82 -159
- package/package.json +11 -13
- package/cli-rs/Cargo.toml +0 -45
- package/cli-rs/README.md +0 -41
- package/cli-rs/build.rs +0 -4
- package/cli-rs/finalize.js +0 -25
- package/cli-rs/rust-toolchain.toml +0 -2
- package/cli-rs/src/app/build/config.rs +0 -54
- package/cli-rs/src/app/build/icon.rs +0 -48
- package/cli-rs/src/app/build/mod.rs +0 -217
- package/cli-rs/src/app/build/release.rs +0 -50
- package/cli-rs/src/app/create/icon.png +0 -0
- package/cli-rs/src/app/create/inquire.rs +0 -189
- package/cli-rs/src/app/create/mod.rs +0 -74
- package/cli-rs/src/app/create/readme.md +0 -71
- package/cli-rs/src/app/help.rs +0 -77
- package/cli-rs/src/app/mod.rs +0 -39
- package/cli-rs/src/app/shared/file_sorter.rs +0 -34
- package/cli-rs/src/app/shared/mod.rs +0 -62
- package/cli-rs/src/app/shared/platforms.rs +0 -69
- package/cli-rs/src/lib.rs +0 -13
- package/cli-rs/src/main.rs +0 -10
- package/cli-rs/tslink.toml +0 -2
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
use ahqstore_types::{
|
|
2
|
-
AHQStoreApplication, DownloadUrl, InstallType, InstallerFormat, InstallerOptions,
|
|
3
|
-
InstallerOptionsLinux, InstallerOptionsWin32, Str,
|
|
4
|
-
};
|
|
5
|
-
use lazy_static::lazy_static;
|
|
6
|
-
use reqwest::blocking::{Client, ClientBuilder};
|
|
7
|
-
use serde::{Deserialize, Serialize};
|
|
8
|
-
use serde_json::{from_str, to_string, to_string_pretty};
|
|
9
|
-
use std::{collections::HashMap, env, fs, process};
|
|
10
|
-
|
|
11
|
-
use crate::app::{ERR, WARN};
|
|
12
|
-
|
|
13
|
-
use super::INFO;
|
|
14
|
-
|
|
15
|
-
mod config;
|
|
16
|
-
mod icon;
|
|
17
|
-
mod release;
|
|
18
|
-
use config::*;
|
|
19
|
-
use icon::*;
|
|
20
|
-
use release::*;
|
|
21
|
-
|
|
22
|
-
lazy_static! {
|
|
23
|
-
pub static ref CLIENT: Client = ClientBuilder::new()
|
|
24
|
-
.user_agent("AHQ Store / App Builder")
|
|
25
|
-
.build()
|
|
26
|
-
.unwrap();
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
#[derive(Debug, Deserialize, Serialize)]
|
|
30
|
-
struct GHRelease {
|
|
31
|
-
pub upload_url: String,
|
|
32
|
-
pub assets: Vec<GHAsset>,
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
#[derive(Debug, Deserialize, Serialize)]
|
|
36
|
-
struct GHAsset {
|
|
37
|
-
pub name: String,
|
|
38
|
-
pub browser_download_url: String,
|
|
39
|
-
}
|
|
40
|
-
pub fn build_config(upload: bool, gh_action: bool) {
|
|
41
|
-
let Some(_) = fs::read_dir("./.ahqstore").ok() else {
|
|
42
|
-
ERR.println(&".ahqstore dir couldn't be accessed!");
|
|
43
|
-
process::exit(1);
|
|
44
|
-
};
|
|
45
|
-
if !gh_action {
|
|
46
|
-
INFO.print(&"INFO ");
|
|
47
|
-
println!("Checking .ahqstore");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
let config = get_config();
|
|
51
|
-
|
|
52
|
-
let repo = env::var("GITHUB_REPOSITORY").unwrap_or("%NUL".into());
|
|
53
|
-
|
|
54
|
-
if &repo == "%NUL" {
|
|
55
|
-
ERR.println(&"GITHUB_REPOSITORY not set");
|
|
56
|
-
process::exit(1);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
let r_id = env::var("RELEASE_ID").unwrap_or("latest".into());
|
|
60
|
-
|
|
61
|
-
if &r_id == "latest" && upload {
|
|
62
|
-
ERR.println(&"RELEASE_ID variable not present");
|
|
63
|
-
process::exit(1);
|
|
64
|
-
};
|
|
65
|
-
if &r_id == "latest" {
|
|
66
|
-
INFO.print(&"INFO ");
|
|
67
|
-
println!("Getting latest release");
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
let gh_token = env::var("GH_TOKEN").unwrap_or("".into());
|
|
71
|
-
|
|
72
|
-
if &gh_token == "" && upload {
|
|
73
|
-
ERR.println(&"GH_TOKEN variable not present");
|
|
74
|
-
process::exit(1);
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
let (version, gh_r) = fetch_release(&repo, &r_id, &gh_token);
|
|
78
|
-
|
|
79
|
-
let icon = get_icon(&config.appId);
|
|
80
|
-
#[allow(non_snake_case)]
|
|
81
|
-
let displayImages = get_images(&config.appId);
|
|
82
|
-
|
|
83
|
-
let app_id = config.appId.clone();
|
|
84
|
-
|
|
85
|
-
let mut final_config: AHQStoreApplication = AHQStoreApplication {
|
|
86
|
-
appDisplayName: config.appDisplayName,
|
|
87
|
-
appId: config.appId,
|
|
88
|
-
appShortcutName: config.appShortcutName,
|
|
89
|
-
authorId: config.authorId,
|
|
90
|
-
description: config.description,
|
|
91
|
-
downloadUrls: HashMap::default(),
|
|
92
|
-
icon,
|
|
93
|
-
displayImages,
|
|
94
|
-
install: InstallerOptions {
|
|
95
|
-
installType: config.platform.installType,
|
|
96
|
-
linux: None,
|
|
97
|
-
win32: None,
|
|
98
|
-
},
|
|
99
|
-
repo: config.repo,
|
|
100
|
-
version,
|
|
101
|
-
site: None,
|
|
102
|
-
source: None
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
if let Some(platform) = config.platform.win32Platform {
|
|
106
|
-
match (&platform, &final_config.install.installType) {
|
|
107
|
-
(&InstallerFormat::WindowsZip, _) => {}
|
|
108
|
-
(_, &InstallType::PerUser | &InstallType::Computer) => {
|
|
109
|
-
WARN.println(
|
|
110
|
-
&"Setting PerUser or Computer in a non WindowsZip install type does not have any effect",
|
|
111
|
-
);
|
|
112
|
-
process::exit(1);
|
|
113
|
-
}
|
|
114
|
-
_ => {}
|
|
115
|
-
};
|
|
116
|
-
let Some(options) = config.platform.win32Options else {
|
|
117
|
-
ERR.println(&"Win32 Options not found!");
|
|
118
|
-
process::exit(1);
|
|
119
|
-
};
|
|
120
|
-
let Some(finder) = config.finder.windowsFinder else {
|
|
121
|
-
ERR.println(&"Win32 Finder Config not found!");
|
|
122
|
-
process::exit(1);
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
let assets = find_assets(&gh_r, &finder);
|
|
126
|
-
|
|
127
|
-
if assets.len() > 1 {
|
|
128
|
-
ERR.println(&"Multiple assets found");
|
|
129
|
-
process::exit(1);
|
|
130
|
-
}
|
|
131
|
-
if assets.len() == 0 {
|
|
132
|
-
ERR.println(&"No assets found");
|
|
133
|
-
process::exit(1);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
final_config.downloadUrls.insert(
|
|
137
|
-
1,
|
|
138
|
-
DownloadUrl {
|
|
139
|
-
installerType: platform,
|
|
140
|
-
url: assets[0].browser_download_url.clone(),
|
|
141
|
-
},
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
final_config.install.win32 = Some(InstallerOptionsWin32 {
|
|
145
|
-
assetId: 1,
|
|
146
|
-
deps: Some(options.deps),
|
|
147
|
-
exec: options.zip_file_exec.map_or(None, |a| Some(a.to_string())),
|
|
148
|
-
installerArgs: options
|
|
149
|
-
.exe_installer_args
|
|
150
|
-
.map_or(None, |a| Some(a.iter().map(|x| x.to_string()).collect())),
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if let Some(platform) = config.platform.linuxPlatform {
|
|
155
|
-
let Some(finder) = config.finder.linuxFinder else {
|
|
156
|
-
ERR.println(&"Linux Finder Config not found!");
|
|
157
|
-
process::exit(1);
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
let assets = find_assets(&gh_r, &finder);
|
|
161
|
-
|
|
162
|
-
if assets.len() > 1 {
|
|
163
|
-
ERR.println(&"Multiple assets found");
|
|
164
|
-
process::exit(1);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
final_config.downloadUrls.insert(
|
|
168
|
-
2,
|
|
169
|
-
DownloadUrl {
|
|
170
|
-
installerType: platform,
|
|
171
|
-
url: assets[0].browser_download_url.clone(),
|
|
172
|
-
},
|
|
173
|
-
);
|
|
174
|
-
|
|
175
|
-
final_config.install.linux = Some(InstallerOptionsLinux {
|
|
176
|
-
assetId: 2
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
final_config.site = config.site;
|
|
181
|
-
final_config.source = config.redistributed;
|
|
182
|
-
|
|
183
|
-
let config_file = to_string_pretty(&final_config).unwrap();
|
|
184
|
-
let config_file = to_string(config_file.as_bytes()).unwrap();
|
|
185
|
-
|
|
186
|
-
if !gh_action {
|
|
187
|
-
println!("Bytes: ahqstore.json");
|
|
188
|
-
println!("{}", &config_file);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
if upload {
|
|
192
|
-
let uup = gh_r
|
|
193
|
-
.upload_url
|
|
194
|
-
.replace("{?name,label}", &format!("?name={app_id}.txt"));
|
|
195
|
-
|
|
196
|
-
let resp = CLIENT
|
|
197
|
-
.post(uup)
|
|
198
|
-
.header("Content-Length", config_file.len())
|
|
199
|
-
.header("Content-Type", "text/plain")
|
|
200
|
-
.header("Accept", "application/json")
|
|
201
|
-
.body(config_file)
|
|
202
|
-
.bearer_auth(&gh_token)
|
|
203
|
-
.send()
|
|
204
|
-
.unwrap()
|
|
205
|
-
.text()
|
|
206
|
-
.unwrap();
|
|
207
|
-
|
|
208
|
-
if gh_action {
|
|
209
|
-
let val: GHAsset = from_str(&resp).unwrap();
|
|
210
|
-
|
|
211
|
-
println!("AHQ_STORE_FILE_URL={}", &val.browser_download_url);
|
|
212
|
-
} else {
|
|
213
|
-
INFO.println(&"GitHub Response");
|
|
214
|
-
println!("{resp}");
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
use std::process;
|
|
2
|
-
|
|
3
|
-
use serde_json::{from_str, to_string};
|
|
4
|
-
use sha2::{Digest, Sha256};
|
|
5
|
-
|
|
6
|
-
use crate::app::{
|
|
7
|
-
build::{GHRelease, Str},
|
|
8
|
-
ERR, WARN,
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
use super::CLIENT;
|
|
12
|
-
|
|
13
|
-
pub fn fetch_release(repo: &str, r_id: &str, gh_token: &str) -> (Str, GHRelease) {
|
|
14
|
-
let Ok(resp) = ({
|
|
15
|
-
let mut resp = CLIENT.get(format!(
|
|
16
|
-
"https://api.github.com/repos/{repo}/releases/{r_id}"
|
|
17
|
-
));
|
|
18
|
-
|
|
19
|
-
if gh_token != "" {
|
|
20
|
-
resp = resp.bearer_auth(gh_token);
|
|
21
|
-
} else {
|
|
22
|
-
WARN.println(&"You may set GH_TOKEN environment variable to load private repos");
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
resp.send()
|
|
26
|
-
}) else {
|
|
27
|
-
ERR.println(&"Unable to fetch release");
|
|
28
|
-
process::exit(1)
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let Ok(release) = resp.text() else {
|
|
32
|
-
ERR.println(&"Unable to read release");
|
|
33
|
-
process::exit(1);
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
let Ok(resp) = from_str::<GHRelease>(&release) else {
|
|
37
|
-
ERR.println(&"Unable to parse release");
|
|
38
|
-
process::exit(1);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
let mut hasher = Sha256::new();
|
|
42
|
-
|
|
43
|
-
hasher.update(release.as_bytes());
|
|
44
|
-
|
|
45
|
-
let hashed = hasher.finalize();
|
|
46
|
-
let hashed = hashed.to_vec();
|
|
47
|
-
let version = to_string(&hashed).unwrap_or("**UNKNOWN**".to_string());
|
|
48
|
-
|
|
49
|
-
(version, resp)
|
|
50
|
-
}
|
|
Binary file
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
use std::process;
|
|
2
|
-
|
|
3
|
-
use ahqstore_types::{AppRepo, InstallerFormat};
|
|
4
|
-
use inquire::{
|
|
5
|
-
list_option::ListOption,
|
|
6
|
-
validator::{ErrorMessage, Validation},
|
|
7
|
-
Editor, MultiSelect, Text,
|
|
8
|
-
};
|
|
9
|
-
use serde::{Deserialize, Serialize};
|
|
10
|
-
|
|
11
|
-
use crate::app::{
|
|
12
|
-
build::CLIENT,
|
|
13
|
-
shared::{Config, IMetadata, IPlatform},
|
|
14
|
-
ERR, INFO,
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
#[derive(Serialize, Deserialize)]
|
|
18
|
-
struct ServerUserResp {
|
|
19
|
-
pub linked_acc: Vec<String>,
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
pub fn inquire<'a>() -> (String, Config<'a>) {
|
|
23
|
-
INFO.println(&"Generating a random Application ID");
|
|
24
|
-
let Ok(app_id) = Text::new("Application ID:")
|
|
25
|
-
.with_default(&gen_appid())
|
|
26
|
-
.prompt()
|
|
27
|
-
else {
|
|
28
|
-
ERR.println(&"Must Enter an ID");
|
|
29
|
-
process::exit(1);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
let Ok(app_name) = Text::new("Start menu entry name:")
|
|
33
|
-
.with_default("Application")
|
|
34
|
-
.prompt()
|
|
35
|
-
else {
|
|
36
|
-
ERR.println(&"Must Enter a name");
|
|
37
|
-
process::exit(1);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
let Ok(display_name) = Text::new("Application Display Name:")
|
|
41
|
-
.with_default("My Cool App")
|
|
42
|
-
.prompt()
|
|
43
|
-
else {
|
|
44
|
-
ERR.println(&"Must Enter a name");
|
|
45
|
-
process::exit(1);
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
let Ok(user_id) = Text::new("Your AHQ Store Author ID:").prompt() else {
|
|
49
|
-
ERR.println(&"Must Enter an ID");
|
|
50
|
-
process::exit(1);
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
let Ok(desc) = Editor::new("Enter your app description").prompt() else {
|
|
54
|
-
ERR.println(&"Must Enter a description");
|
|
55
|
-
process::exit(1);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
let Ok(repo) = Text::new("Enter your app repository:")
|
|
59
|
-
.with_default("owner/repoName")
|
|
60
|
-
.with_validator(|string: &str| {
|
|
61
|
-
if string.split("/").collect::<Vec<_>>().len() == 2 {
|
|
62
|
-
Ok(Validation::Valid)
|
|
63
|
-
} else {
|
|
64
|
-
Ok(Validation::Invalid(ErrorMessage::Custom(
|
|
65
|
-
"Must be in the format owner/repoName".into(),
|
|
66
|
-
)))
|
|
67
|
-
}
|
|
68
|
-
})
|
|
69
|
-
.prompt()
|
|
70
|
-
else {
|
|
71
|
-
ERR.println(&"Must Enter a repository");
|
|
72
|
-
process::exit(1);
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
let [owner, repo] = repo.split("/").collect::<Vec<_>>()[..] else {
|
|
76
|
-
panic!("Repo Parsing Failed")
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
INFO.println(&"Validating author id & repo");
|
|
80
|
-
|
|
81
|
-
let val: Option<()> = (|| {
|
|
82
|
-
let data: ServerUserResp = CLIENT
|
|
83
|
-
.get(format!(
|
|
84
|
-
"https://ahqstore-server.onrender.com/users/{}",
|
|
85
|
-
&user_id
|
|
86
|
-
))
|
|
87
|
-
.send()
|
|
88
|
-
.ok()?
|
|
89
|
-
.json()
|
|
90
|
-
.ok()?;
|
|
91
|
-
|
|
92
|
-
if data.linked_acc.contains(&owner.into()) {
|
|
93
|
-
return Some(());
|
|
94
|
-
}
|
|
95
|
-
None
|
|
96
|
-
})();
|
|
97
|
-
|
|
98
|
-
if let None = val {
|
|
99
|
-
ERR.println(
|
|
100
|
-
&r#"Could not validate author id with github username. It may be because:
|
|
101
|
-
- The account id provided is not valid
|
|
102
|
-
- The account id has developer mode disabled
|
|
103
|
-
- The GitHub repo owner doesn't seem to be in the list of linked_accounts
|
|
104
|
-
- The GitHub repo is invalid"#,
|
|
105
|
-
);
|
|
106
|
-
process::exit(1);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
let validator = |input: &[ListOption<&InstallerFormat>]| {
|
|
110
|
-
if input.len() == 0 {
|
|
111
|
-
return Ok(Validation::Invalid(
|
|
112
|
-
"You must select at least one target".into(),
|
|
113
|
-
));
|
|
114
|
-
}
|
|
115
|
-
if input.len() > 2 {
|
|
116
|
-
return Ok(Validation::Invalid(
|
|
117
|
-
"You can only select two targets".into(),
|
|
118
|
-
));
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
let flagged = vec![0, 1, 2, 3];
|
|
122
|
-
if input
|
|
123
|
-
.iter()
|
|
124
|
-
.filter(|a| flagged.contains(&a.index))
|
|
125
|
-
.collect::<Vec<_>>()
|
|
126
|
-
.len()
|
|
127
|
-
> 1
|
|
128
|
-
{
|
|
129
|
-
return Ok(Validation::Invalid(
|
|
130
|
-
"You can only select one bundle target for a platform".into(),
|
|
131
|
-
));
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
Ok(Validation::Valid)
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
let Ok(platforms) = MultiSelect::new(
|
|
138
|
-
"Which platforms do you intend to support?",
|
|
139
|
-
vec![
|
|
140
|
-
InstallerFormat::WindowsZip,
|
|
141
|
-
InstallerFormat::WindowsInstallerMsi,
|
|
142
|
-
InstallerFormat::WindowsInstallerExe,
|
|
143
|
-
InstallerFormat::WindowsUWPMsix,
|
|
144
|
-
InstallerFormat::LinuxAppImage,
|
|
145
|
-
],
|
|
146
|
-
)
|
|
147
|
-
.with_default(&[0])
|
|
148
|
-
.with_validator(validator)
|
|
149
|
-
.prompt() else {
|
|
150
|
-
ERR.println(&"Must Select a platform");
|
|
151
|
-
process::exit(1);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
(
|
|
155
|
-
app_id.clone(),
|
|
156
|
-
IMetadata::new(
|
|
157
|
-
app_id,
|
|
158
|
-
app_name,
|
|
159
|
-
display_name,
|
|
160
|
-
user_id,
|
|
161
|
-
desc,
|
|
162
|
-
AppRepo {
|
|
163
|
-
author: owner.into(),
|
|
164
|
-
repo: repo.into(),
|
|
165
|
-
},
|
|
166
|
-
IPlatform::new(platforms),
|
|
167
|
-
),
|
|
168
|
-
)
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
fn gen_appid() -> String {
|
|
172
|
-
let mut string = String::new();
|
|
173
|
-
|
|
174
|
-
use rand::seq::SliceRandom;
|
|
175
|
-
|
|
176
|
-
let val = vec![
|
|
177
|
-
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
|
|
178
|
-
"t", "u", "v", "w", "s", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
|
|
179
|
-
"M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "S", "Y", "Z", "0", "1", "2", "3", "4",
|
|
180
|
-
"5", "6", "7", "8", "9"
|
|
181
|
-
];
|
|
182
|
-
|
|
183
|
-
for _ in 0..40 {
|
|
184
|
-
let val = val.choose(&mut rand::thread_rng()).unwrap();
|
|
185
|
-
string.push_str(val);
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
string
|
|
189
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
mod inquire;
|
|
2
|
-
use std::{fs, process};
|
|
3
|
-
|
|
4
|
-
use inquire::*;
|
|
5
|
-
use serde_json::to_string_pretty;
|
|
6
|
-
|
|
7
|
-
use super::{ERR, INFO, WARN};
|
|
8
|
-
|
|
9
|
-
pub fn create(force: bool) {
|
|
10
|
-
let (id, config) = inquire();
|
|
11
|
-
|
|
12
|
-
create_dir(force);
|
|
13
|
-
|
|
14
|
-
let succ = (|| {
|
|
15
|
-
let config_file = to_string_pretty(&config).ok()?;
|
|
16
|
-
fs::write("./.ahqstore/config.json", config_file).ok()?;
|
|
17
|
-
|
|
18
|
-
let base_img = format!("./.ahqstore/images/{}", &id);
|
|
19
|
-
|
|
20
|
-
fs::create_dir_all(&base_img).ok()?;
|
|
21
|
-
|
|
22
|
-
let icon = include_bytes!("./icon.png");
|
|
23
|
-
fs::write(format!("{}/icon.png", &base_img), icon).ok()?;
|
|
24
|
-
|
|
25
|
-
let readme = include_str!("./readme.md");
|
|
26
|
-
fs::write("./.ahqstore/README.md", readme).ok()
|
|
27
|
-
})()
|
|
28
|
-
.is_some();
|
|
29
|
-
|
|
30
|
-
if !succ {
|
|
31
|
-
ERR.println(&"Failed to populate .ahqstore");
|
|
32
|
-
process::exit(1);
|
|
33
|
-
} else {
|
|
34
|
-
println!("🇩🇴🇳🇪");
|
|
35
|
-
println!(
|
|
36
|
-
r#"████████████████████████████████████████████████████████████████▀█
|
|
37
|
-
█─█─██▀▄─██▄─▄▄─█▄─▄▄─█▄─█─▄███─▄▄▄─█─▄▄─█▄─▄▄▀█▄─▄█▄─▀█▄─▄█─▄▄▄▄█
|
|
38
|
-
█─▄─██─▀─███─▄▄▄██─▄▄▄██▄─▄████─███▀█─██─██─██─██─███─█▄▀─██─██▄─█
|
|
39
|
-
▀▄▀▄▀▄▄▀▄▄▀▄▄▄▀▀▀▄▄▄▀▀▀▀▄▄▄▀▀▀▀▄▄▄▄▄▀▄▄▄▄▀▄▄▄▄▀▀▄▄▄▀▄▄▄▀▀▄▄▀▄▄▄▄▄▀
|
|
40
|
-
"#
|
|
41
|
-
);
|
|
42
|
-
INFO.println(&"Do not forget to edit config.json and finder.json\nMore details about all the files is present in README.md");
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
pub fn create_dir(force: bool) {
|
|
47
|
-
if let Err(_) = fs::create_dir("./.ahqstore") {
|
|
48
|
-
if force {
|
|
49
|
-
WARN.println(&"--force detected\nRemoving dir .ahqstore");
|
|
50
|
-
|
|
51
|
-
let succ = (|| {
|
|
52
|
-
fs::remove_dir_all("./.ahqstore").ok()?;
|
|
53
|
-
fs::create_dir_all("./.ahqstore").ok()?;
|
|
54
|
-
|
|
55
|
-
Some(())
|
|
56
|
-
})()
|
|
57
|
-
.is_some();
|
|
58
|
-
|
|
59
|
-
if succ {
|
|
60
|
-
INFO.println(&".ahqstore directory created, initializing data...");
|
|
61
|
-
} else {
|
|
62
|
-
ERR.println(&"Failed to create .ahqstore directory");
|
|
63
|
-
process::exit(1);
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
ERR.println(
|
|
67
|
-
&"Failed to create .ahqstore directory\nHint: Use --force option to ignore this error",
|
|
68
|
-
);
|
|
69
|
-
process::exit(1);
|
|
70
|
-
}
|
|
71
|
-
} else {
|
|
72
|
-
INFO.println(&"Created .ahqstore directory, initializing data...");
|
|
73
|
-
}
|
|
74
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# AHQ Store Cli
|
|
2
|
-
|
|
3
|
-
Do edit the config.json
|
|
4
|
-
|
|
5
|
-
The schema has been shown below
|
|
6
|
-
|
|
7
|
-
## config.json
|
|
8
|
-
|
|
9
|
-
```ts
|
|
10
|
-
type Platform =
|
|
11
|
-
// Windows Platforms + Updater & UnInstaller Support
|
|
12
|
-
| "WindowsZip"
|
|
13
|
-
| "WindowsInstallerMsi"
|
|
14
|
-
|
|
15
|
-
// Not Implemented
|
|
16
|
-
| "WindowsInstallerExe"
|
|
17
|
-
| "WindowsUWPMsix"
|
|
18
|
-
|
|
19
|
-
// Linux Platform + Updater & UnInstaller Support
|
|
20
|
-
| "LinuxAppImage";
|
|
21
|
-
|
|
22
|
-
type Win32Deps = "AHQStoreAPI" | "Node21" | "Node18";
|
|
23
|
-
|
|
24
|
-
interface ConfigJSON {
|
|
25
|
-
[key: string]: {
|
|
26
|
-
appId: string; //application id provided by AHQ Store DEVS
|
|
27
|
-
appInstalledName: string; //App Start Menu Entry + Desktop Shortcut Name
|
|
28
|
-
appDisplayName: string; //App display name
|
|
29
|
-
authorId: string; //Your User ID
|
|
30
|
-
shortDesc: string; //Short Description (max 48words)
|
|
31
|
-
description: string; //MultiLine App Description
|
|
32
|
-
repo: {
|
|
33
|
-
author: string; //Your GitHub username
|
|
34
|
-
repo: string; //Repo URL
|
|
35
|
-
};
|
|
36
|
-
finder: {
|
|
37
|
-
windowsFinder?: {
|
|
38
|
-
startsWith?: string; // The Windows Bundled app should startWith?
|
|
39
|
-
contains?: string; // The Windows Bundled app should include?
|
|
40
|
-
endsWith?: string; // The Windows Bundled app should endWith?
|
|
41
|
-
};
|
|
42
|
-
linuxFinder?: {
|
|
43
|
-
startsWith?: string; // The Linux Bundled app should startWith?
|
|
44
|
-
contains?: string; // The Linux Bundled app should include?
|
|
45
|
-
endsWith?: string; // The Linux Bundled app should endWith?
|
|
46
|
-
};
|
|
47
|
-
};
|
|
48
|
-
platform: {
|
|
49
|
-
installType: "Both" | "PerUser" | "Computer"; // Install Type
|
|
50
|
-
win32Platform?: Platform; // What type of binary does your app provide to AHQ Store
|
|
51
|
-
linuxPlatform?: Platform; // <-- Same as win32Platform -->
|
|
52
|
-
win32Options?: {
|
|
53
|
-
deps: Win32Deps[]; // Win32 Custom Deps
|
|
54
|
-
zip_file_exec?: string; // Exe to Link via our installer (WindowsZIP)
|
|
55
|
-
exe_installer_args?: string[]; // Args to run to your custom installer (WindowsInstallerExe)
|
|
56
|
-
};
|
|
57
|
-
linuxOptions?: {};
|
|
58
|
-
};
|
|
59
|
-
site?: string; // Your app's website
|
|
60
|
-
redistributed?: string; // Redistributed page (not for public)
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## icon.png
|
|
66
|
-
|
|
67
|
-
Your application icon that'll be bundled in the app metadata file
|
|
68
|
-
|
|
69
|
-
## images/<app-id>/\*
|
|
70
|
-
|
|
71
|
-
Place any image(s) [upto 10] that will be placed in the app modal in AHQ Store
|
package/cli-rs/src/app/help.rs
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
use chalk_rs::Chalk;
|
|
2
|
-
|
|
3
|
-
pub fn main_help() -> String {
|
|
4
|
-
let mut chalk = Chalk::new();
|
|
5
|
-
|
|
6
|
-
let cli = chalk.blue().bold().string(&"AHQ Store CLI");
|
|
7
|
-
|
|
8
|
-
let usage = chalk.green().bold().string(&"Usage:");
|
|
9
|
-
|
|
10
|
-
let cmds = chalk.green().bold().string(&"Commands:");
|
|
11
|
-
let help = chalk.cyan().bold().string(&"help");
|
|
12
|
-
let create = chalk.cyan().bold().string(&"create");
|
|
13
|
-
let build = chalk.cyan().bold().string(&"build");
|
|
14
|
-
let upload = chalk.cyan().bold().string(&"build");
|
|
15
|
-
|
|
16
|
-
let opt = chalk.yellow().bold().string(&"Options:");
|
|
17
|
-
let force = chalk.cyan().bold().string(&"--force, -f");
|
|
18
|
-
|
|
19
|
-
let env = chalk.yellow().bold().string(&"Required ENV:");
|
|
20
|
-
let app_id = chalk.cyan().bold().string(&"APP_ID");
|
|
21
|
-
let gh_token = chalk.cyan().bold().string(&"GH_TOKEN");
|
|
22
|
-
let gh_repo = chalk.cyan().bold().string(&"GITHUB_REPOSITORY");
|
|
23
|
-
let gh_action = chalk.cyan().bold().string(&"GITHUB_ACTION");
|
|
24
|
-
let r_id = chalk.cyan().bold().string(&"RELEASE_ID");
|
|
25
|
-
|
|
26
|
-
let optional = chalk.yellow().bold().string(&"(Optional)");
|
|
27
|
-
|
|
28
|
-
format!(
|
|
29
|
-
r#"{cli}
|
|
30
|
-
Ship your apps to the ahq store quickly and efficiently
|
|
31
|
-
|
|
32
|
-
{usage}
|
|
33
|
-
ahqstore (command) [options]
|
|
34
|
-
{cmds}
|
|
35
|
-
{help}
|
|
36
|
-
Shows the help menu
|
|
37
|
-
{create}
|
|
38
|
-
Generates AHQ Store config files required to ship your apps
|
|
39
|
-
{opt}
|
|
40
|
-
{force} Override Existing contents if .ahqstore dir isn't empty
|
|
41
|
-
{upload}
|
|
42
|
-
Build & Upload ahqstore config file
|
|
43
|
-
{env}
|
|
44
|
-
{app_id} {optional} Application Id (required if your config has more than 1 appIds)
|
|
45
|
-
{r_id} GitHub Release Id
|
|
46
|
-
{gh_token} GitHub Token
|
|
47
|
-
{gh_repo} GitHub owner & repo name, eg ahqstore/app
|
|
48
|
-
(Equivalent to GITHUB_REPOSITORY variable in GitHub actions)
|
|
49
|
-
{gh_action} {optional} Set this env to anything to specify that it is running in an GitHub Action
|
|
50
|
-
(Outputs AHQ_STORE_FILE_URL=<url>)
|
|
51
|
-
{build}
|
|
52
|
-
Build the ahqstore config file
|
|
53
|
-
{env}
|
|
54
|
-
{app_id} {optional} Application Id (required if your config has more than 1 appIds)
|
|
55
|
-
{r_id} GitHub Release Id
|
|
56
|
-
{gh_token} GitHub Token
|
|
57
|
-
{gh_repo} GitHub owner & repo name, eg ahqstore/app
|
|
58
|
-
(Equivalent to GITHUB_REPOSITORY variable in GitHub actions)
|
|
59
|
-
{gh_action} {optional} Set this env to anything to specify that it is running in an GitHub Action
|
|
60
|
-
(Outputs AHQ_STORE_FILE_URL=<url>)"#
|
|
61
|
-
)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
pub fn not_found(name: &str) -> String {
|
|
65
|
-
let mut chalk = Chalk::new();
|
|
66
|
-
|
|
67
|
-
let cmd = chalk.red().bold().string(&"Command not found:");
|
|
68
|
-
let tip = chalk.green().bold().string(&"Tip:");
|
|
69
|
-
let astore = chalk.cyan().bold().string(&"ahqstore");
|
|
70
|
-
|
|
71
|
-
format!(
|
|
72
|
-
r#"{cmd} {name}
|
|
73
|
-
|
|
74
|
-
{tip}
|
|
75
|
-
Write {astore} to view the help menu"#
|
|
76
|
-
)
|
|
77
|
-
}
|