@ahqstore/cli 0.5.2 → 0.6.0

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.
@@ -1,142 +1,114 @@
1
- use std::process;
2
-
3
- use ahqstore_types::AppRepo;
4
- use inquire::{
5
- validator::{ErrorMessage, Validation},
6
- Editor, Text,
7
- };
8
- use serde::{Deserialize, Serialize};
9
-
10
- use crate::app::{
11
- shared::{Config, IMetadata, IPlatform},
12
- ERR, INFO,
13
- };
14
-
15
- #[derive(Serialize, Deserialize)]
16
- struct ServerUserResp {
17
- pub linked_acc: Vec<String>,
18
- }
19
-
20
- pub fn inquire<'a>() -> (String, Config<'a>) {
21
- INFO.println(&"Generating a random Application ID");
22
- let Ok(app_id) = Text::new("Application ID:")
23
- .with_default(&gen_appid())
24
- .prompt()
25
- else {
26
- ERR.println(&"Must Enter an ID");
27
- process::exit(1);
28
- };
29
-
30
- let Ok(app_name) = Text::new("Start menu entry name:")
31
- .with_default("Application")
32
- .prompt()
33
- else {
34
- ERR.println(&"Must Enter a name");
35
- process::exit(1);
36
- };
37
-
38
- let Ok(display_name) = Text::new("Application Display Name:")
39
- .with_default("My Cool App")
40
- .prompt()
41
- else {
42
- ERR.println(&"Must Enter a name");
43
- process::exit(1);
44
- };
45
-
46
- let Ok(user_id) = Text::new("Your AHQ Store Author ID:").prompt() else {
47
- ERR.println(&"Must Enter an ID");
48
- process::exit(1);
49
- };
50
-
51
- let Ok(desc) = Editor::new("Enter your app description").prompt() else {
52
- ERR.println(&"Must Enter a description");
53
- process::exit(1);
54
- };
55
-
56
- let Ok(repo) = Text::new("Enter your app repository:")
57
- .with_default("owner/repoName")
58
- .with_validator(|string: &str| {
59
- if string.split("/").collect::<Vec<_>>().len() == 2 {
60
- Ok(Validation::Valid)
61
- } else {
62
- Ok(Validation::Invalid(ErrorMessage::Custom(
63
- "Must be in the format owner/repoName".into(),
64
- )))
65
- }
66
- })
67
- .prompt()
68
- else {
69
- ERR.println(&"Must Enter a repository");
70
- process::exit(1);
71
- };
72
-
73
- let [owner, repo] = repo.split("/").collect::<Vec<_>>()[..] else {
74
- panic!("Repo Parsing Failed")
75
- };
76
-
77
- INFO.println(&"Validating author id & repo");
78
-
79
- // let val: Option<()> = (|| {
80
- // let data: ServerUserResp = CLIENT
81
- // .get(format!(
82
- // "https://ahqstore-server.onrender.com/users/{}",
83
- // &user_id
84
- // ))
85
- // .send()
86
- // .ok()?
87
- // .json()
88
- // .ok()?;
89
-
90
- // if data.linked_acc.contains(&owner.into()) {
91
- // return Some(());
92
- // }
93
- // None
94
- // })();
95
-
96
- // if let None = val {
97
- // ERR.println(
98
- // &r#"Could not validate author id with github username. It may be because:
99
- // - The account id provided is not valid
100
- // - The account id has developer mode disabled
101
- // - The GitHub repo owner doesn't seem to be in the list of linked_accounts
102
- // - The GitHub repo is invalid"#,
103
- // );
104
- // process::exit(1);
105
- // }
106
-
107
- (
108
- app_id.clone(),
109
- IMetadata::new(
110
- app_id,
111
- app_name,
112
- display_name,
113
- user_id,
114
- desc,
115
- AppRepo {
116
- author: owner.into(),
117
- repo: repo.into(),
118
- },
119
- IPlatform::new()
120
- ),
121
- )
122
- }
123
-
124
- fn gen_appid() -> String {
125
- let mut string = String::new();
126
-
127
- use rand::seq::SliceRandom;
128
-
129
- let val = vec![
130
- "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
131
- "t", "u", "v", "w", "s", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
132
- "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "S", "Y", "Z", "0", "1", "2", "3", "4",
133
- "5", "6", "7", "8", "9"
134
- ];
135
-
136
- for _ in 0..40 {
137
- let val = val.choose(&mut rand::thread_rng()).unwrap();
138
- string.push_str(val);
139
- }
140
-
141
- string
142
- }
1
+ use std::process;
2
+
3
+ use ahqstore_types::AppRepo;
4
+ use inquire::{
5
+ validator::{ErrorMessage, Validation},
6
+ Editor, Text,
7
+ };
8
+ use serde::{Deserialize, Serialize};
9
+
10
+ use crate::app::{
11
+ shared::{Config, IMetadata, IPlatform},
12
+ ERR, INFO,
13
+ };
14
+
15
+ #[derive(Serialize, Deserialize)]
16
+ struct ServerUserResp {
17
+ pub linked_acc: Vec<String>,
18
+ }
19
+
20
+ pub fn inquire<'a>() -> (String, Config<'a>) {
21
+ INFO.println(&"Generating a random Application ID");
22
+ let Ok(app_id) = Text::new("Application ID:")
23
+ .with_default(&gen_appid())
24
+ .prompt()
25
+ else {
26
+ ERR.println(&"Must Enter an ID");
27
+ process::exit(1);
28
+ };
29
+
30
+ let Ok(app_name) = Text::new("Start menu entry name:")
31
+ .with_default("Application")
32
+ .prompt()
33
+ else {
34
+ ERR.println(&"Must Enter a name");
35
+ process::exit(1);
36
+ };
37
+
38
+ let Ok(display_name) = Text::new("Application Display Name:")
39
+ .with_default("My Cool App")
40
+ .prompt()
41
+ else {
42
+ ERR.println(&"Must Enter a name");
43
+ process::exit(1);
44
+ };
45
+
46
+ let Ok(user_id) = Text::new("Your AHQ Store Author ID:").prompt() else {
47
+ ERR.println(&"Must Enter an ID");
48
+ process::exit(1);
49
+ };
50
+
51
+ let Ok(desc) = Editor::new("Enter your app description").prompt() else {
52
+ ERR.println(&"Must Enter a description");
53
+ process::exit(1);
54
+ };
55
+
56
+ let Ok(repo) = Text::new("Enter your app repository:")
57
+ .with_default("owner/repoName")
58
+ .with_validator(|string: &str| {
59
+ if string.split("/").collect::<Vec<_>>().len() == 2 {
60
+ Ok(Validation::Valid)
61
+ } else {
62
+ Ok(Validation::Invalid(ErrorMessage::Custom(
63
+ "Must be in the format owner/repoName".into(),
64
+ )))
65
+ }
66
+ })
67
+ .prompt()
68
+ else {
69
+ ERR.println(&"Must Enter a repository");
70
+ process::exit(1);
71
+ };
72
+
73
+ let [owner, repo] = repo.split("/").collect::<Vec<_>>()[..] else {
74
+ panic!("Repo Parsing Failed")
75
+ };
76
+
77
+ INFO.println(&"Validating author id & repo");
78
+
79
+ (
80
+ app_id.clone(),
81
+ IMetadata::new(
82
+ app_id,
83
+ app_name,
84
+ display_name,
85
+ user_id,
86
+ desc,
87
+ AppRepo {
88
+ author: owner.into(),
89
+ repo: repo.into(),
90
+ },
91
+ IPlatform::new()
92
+ ),
93
+ )
94
+ }
95
+
96
+ fn gen_appid() -> String {
97
+ let mut string = String::new();
98
+
99
+ use rand::seq::SliceRandom;
100
+
101
+ let val = vec![
102
+ "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
103
+ "t", "u", "v", "w", "s", "y", "z", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",
104
+ "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "S", "Y", "Z", "0", "1", "2", "3", "4",
105
+ "5", "6", "7", "8", "9"
106
+ ];
107
+
108
+ for _ in 0..40 {
109
+ let val = val.choose(&mut rand::thread_rng()).unwrap();
110
+ string.push_str(val);
111
+ }
112
+
113
+ string
114
+ }
@@ -1,80 +1,74 @@
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
- let readme = include_str!("./readme.es.md");
29
- fs::write("./.ahqstore/README.es.md", readme).ok()?;
30
-
31
- let readme = include_str!("./readme.hi.md");
32
- fs::write("./.ahqstore/README.hi.md", readme).ok()
33
- })()
34
- .is_some();
35
-
36
- if !succ {
37
- ERR.println(&"Failed to populate .ahqstore");
38
- process::exit(1);
39
- } else {
40
- println!("🇩​​​​​🇴​​​​​🇳​​​​​🇪​​​​​");
41
- println!(
42
- r#"████████████████████████████████████████████████████████████████▀█
43
- █─█─██▀▄─██▄─▄▄─█▄─▄▄─█▄─█─▄███─▄▄▄─█─▄▄─█▄─▄▄▀█▄─▄█▄─▀█▄─▄█─▄▄▄▄█
44
- █─▄─██─▀─███─▄▄▄██─▄▄▄██▄─▄████─███▀█─██─██─██─██─███─█▄▀─██─██▄─█
45
- ▀▄▀▄▀▄▄▀▄▄▀▄▄▄▀▀▀▄▄▄▀▀▀▀▄▄▄▀▀▀▀▄▄▄▄▄▀▄▄▄▄▀▄▄▄▄▀▀▄▄▄▀▄▄▄▀▀▄▄▀▄▄▄▄▄▀
46
- "#
47
- );
48
- INFO.println(&"Do not forget to edit config.json and finder.json\nMore details about all the files is present in README.md");
49
- }
50
- }
51
-
52
- pub fn create_dir(force: bool) {
53
- if let Err(_) = fs::create_dir("./.ahqstore") {
54
- if force {
55
- WARN.println(&"--force detected\nRemoving dir .ahqstore");
56
-
57
- let succ = (|| {
58
- fs::remove_dir_all("./.ahqstore").ok()?;
59
- fs::create_dir_all("./.ahqstore").ok()?;
60
-
61
- Some(())
62
- })()
63
- .is_some();
64
-
65
- if succ {
66
- INFO.println(&".ahqstore directory created, initializing data...");
67
- } else {
68
- ERR.println(&"Failed to create .ahqstore directory");
69
- process::exit(1);
70
- }
71
- } else {
72
- ERR.println(
73
- &"Failed to create .ahqstore directory\nHint: Use --force option to ignore this error",
74
- );
75
- process::exit(1);
76
- }
77
- } else {
78
- INFO.println(&"Created .ahqstore directory, initializing data...");
79
- }
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
+ }
80
74
  }
@@ -1,80 +1,13 @@
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
- // Android (Under Development)
23
- | "AndroidLinuxZip";
24
-
25
- interface ConfigJSON {
26
- [key: string]: {
27
- appId: string; //application id provided by AHQ Store DEVS
28
- appInstalledName: string; //App Start Menu Entry + Desktop Shortcut Name
29
- appDisplayName: string; //App display name
30
- authorId: string; //Your User ID
31
- shortDesc: string; //Short Description (max 48words)
32
- description: string; //MultiLine App Description
33
- repo: {
34
- author: string; //Your GitHub username
35
- repo: string; //Repo URL
36
- };
37
- finder: {
38
- [platform: ""]: {
39
- startsWith?: string; // The Bundled app should startWith?
40
- contains?: string; // The Bundled app should include?
41
- endsWith?: string; // The Bundled app should endWith?
42
- };
43
- };
44
- platform: {
45
- // Must be "WindowsZip"| "WindowsInstallerMsi" |"WindowsInstallerExe" | "WindowsUWPMsix"
46
- winAmd64Platform?: Platform; // What type of binary does your app provide to AHQ Store
47
- winArm64Platform?: Platform; // <-- Same as winAmd64Platform -->
48
-
49
- linuxAmd64Platform?: Platform; // Must be LinuxAppImage
50
- linuxArm64Platform?: Platform; // Must be LinuxAppImage
51
- linuxArm64Platform?: Platform; // Must be LinuxAppImage
52
- linuxArm32Platform?: Platform; // Must be LinuxAppImage
53
-
54
- androidUniversalPlatform?: Platform; // Must be AndroidApkZip
55
-
56
- winAmd64Options?: {
57
- zip_file_exec?: string; // Exe to Link via our installer (WindowsZIP)
58
- exe_installer_args?: string[]; // Args to run to your custom installer (WindowsInstallerExe)
59
- };
60
-
61
- winArm64Options?: {
62
- zip_file_exec?: string; // Exe to Link via our installer (WindowsZIP)
63
- exe_installer_args?: string[]; // Args to run to your custom installer (WindowsInstallerExe)
64
- };
65
- };
66
- site?: string; // Your app's website
67
- source?: string; // Your app's website (that contains source code)
68
- redistributed?: string; // You just **cannot** set this
69
- license_or_tos?: string; // Name of License or site of TOS
70
- };
71
- }
72
- ```
73
-
74
- ## images/<app-id>/icon.png
75
-
76
- Your application icon that'll be bundled in the app metadata file
77
-
78
- ## images/<app-id>/\*
79
-
80
- Place any image(s) [upto 10] that will be placed in the app modal in AHQ Store
1
+ # AHQ Store Cli
2
+
3
+ ## config.json
4
+
5
+ Follows the schema as presented [here](https://docs.rs/ahqstore_cli_rs/latest/ahqstore_cli_rs/shared/struct.IMetadata.html)
6
+
7
+ ## images/<app-id>/icon.png
8
+
9
+ Your application icon that'll be bundled in the app metadata file
10
+
11
+ ## images/<app-id>/\*
12
+
13
+ Place any image(s) [upto 10] that will be placed in the app modal in AHQ Store
package/src/app/help.rs CHANGED
@@ -1,77 +1,77 @@
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
- }
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
+ }