Skip to content

Commit 33e858d

Browse files
authored
Merge pull request #259 from J-ZhengLi/remastered
detects running mode by checking config instead of checking executable name & QOL improvements
2 parents 281b587 + afc7a3e commit 33e858d

File tree

52 files changed

+1044
-382
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1044
-382
lines changed

Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ tokio.workspace = true
6262
[dev-dependencies]
6363
rim-test-support = { version = "0.1.0", path = "rim_test/rim-test-support" }
6464

65+
[build-dependencies]
66+
rim_common = { path = "rim_common" }
67+
6568
[target."cfg(windows)".dependencies]
6669
winreg = "0.52.0"
6770
winapi = { version = "0.3", features = ["winuser", "winbase"] }

README.md

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,11 @@ After env setup, it will guide you through installing Rust `toolkit`.
6464
- Debug `installer` mode:
6565
- Commandline interface
6666
```bash
67-
cargo run
67+
cargo dev run --cli --installer
6868
```
6969
- Graphical interface
7070
```bash
71-
cd rim_gui
72-
pnpm run tauri dev
71+
pnpm dev run --installer
7372
```
7473
- Debug `manager` mode:
7574
> Running `manager` is not as straight forward as running in `Installer` mode.
@@ -78,7 +77,7 @@ After env setup, it will guide you through installing Rust `toolkit`.
7877
so you can test `manager`'s functionalities easier.
7978

8079
```bash
81-
cargo dev run-manager
80+
cargo dev run --manager
8281
```
8382

8483
### Release
@@ -140,12 +139,8 @@ Options:
140139

141140
### Manager mode (CLI)
142141

143-
> Manager mode can be activated by:
144-
>
145-
> 1. Renaming the binary to one that contains `manager`, such as `manager-cli`
146-
> 2. Having a `MODE` environment variable set to `manager` before running the program, such as running `export MODE='manager'` in Unix systems.
147-
>
148-
> NOTE: **Manager will be automatically deployed after installation, and must be run inside of the installation directory to avoid crash**
142+
> Manager mode will run after an installation record was detected, and it can also be overridden by
143+
> having a `MODE` environment variable set to `manager` before running the program, such as running `export MODE='manager'` in Unix systems.
149144

150145
```console
151146
Usage: MODE='manager' rim-cli.exe [OPTIONS] [COMMAND]

build.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,6 @@ fn main() {
2323

2424
let edition = env::var(EDITION_OVERRIDE_ENV).unwrap_or(DEFAULT_EDITION.to_string());
2525
println!("cargo::rustc-env=EDITION={edition}");
26+
27+
rim_common::setup_version_info!();
2628
}

locales/en-US.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,5 +162,10 @@
162162
"unable_to_run_check": "unable to perform check, maybe the rule-set wasn't installed properly",
163163
"use_offline_dist_server": "attempt to use offline dist server at: '%{url}'",
164164
"program_does_not_exits": "unable to execute command because the program '%{program}' does not exist in the PATH variable",
165-
"skip_env_modification": "skip modifying environment variables as requested"
165+
"skip_env_modification": "skip modifying environment variables as requested",
166+
"install_record_not_found": "installation record cannot be found at '%{path}', try re-install this program to fix the problem",
167+
"install_dir_is_root": "the program is installed but the installation directory appears to be root or empty, try re-install this program to fix the problem",
168+
"install_dir_is_os_dir": "the program is installed but the installation directory appears to be an OS specific directory '%{path}', try re-install this program to fix the problem",
169+
"uninstall_self_residual_info": "uninstall finished successfully, some files might not get removed until next system reboot",
170+
"duplicated_config_files": "duplicated config file detected at these locations:\n1. %{first}\n2. %{second}\nconfiguration of the first one will be used"
166171
}

locales/zh-CN.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,5 +158,10 @@
158158
"unable_to_run_check": "无法执行检查,可能是规则集未正确安装",
159159
"use_offline_dist_server": "尝试使用 rustup 本地服务器: '%{url}'",
160160
"program_does_not_exits": "无法运行指定命令,应用程序 '%{program}' 不在 PATH 变量中",
161-
"skip_env_modification": "跳过环境变量修改步骤"
161+
"skip_env_modification": "跳过环境变量修改步骤",
162+
"install_record_not_found": "找不到安装记录 '%{path}',请尝试重新安装该程序修复此问题。",
163+
"install_dir_is_root": "程序已安装,但安装目录似乎为空或处于根目录,请尝试重新安装该程序以解决问题。",
164+
"install_dir_is_os_dir": "程序已安装,但其安装目录位于系统专用路径 '%{path}',建议检查或重新安装。",
165+
"uninstall_self_residual_info": "卸载已完成,某些文件将在系统重启后彻底移除。",
166+
"duplicated_config_files": "检查到以下重复配置文件:\n1. %{first}\n2. %{second}\n将读取第一个文件"
162167
}

rim_common/src/dirs.rs

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//! Common Directories that are outside of install dir
2+
3+
use std::{
4+
env,
5+
path::{Path, PathBuf},
6+
};
7+
8+
#[macro_export]
9+
/// Declare a statically allocated `OnceLock` path, and create that directory if it does not exists.
10+
macro_rules! get_path_and_create {
11+
($path_ident:ident, $init:expr) => {{
12+
static $path_ident: std::sync::OnceLock<std::path::PathBuf> = std::sync::OnceLock::new();
13+
$path_ident.get_or_init(|| {
14+
let __path__ = $init;
15+
$crate::utils::ensure_dir(&__path__)
16+
.expect("unable to create one of the directory under installation folder");
17+
__path__
18+
})
19+
}};
20+
}
21+
22+
/// Get a path to user's "home" directory.
23+
///
24+
/// The home directory is determined by a combination of ways
25+
/// with a fallback order:
26+
///
27+
/// 1. The `HOME` environment variable
28+
/// 2. The `USERPROFILE` environment variable (Windows only)
29+
/// 3. The [`home_dir`](dirs::home_dir) function of the `dirs` crate
30+
///
31+
/// # Panic
32+
///
33+
/// Will panic if such directory cannot be determined by neither the `HOME` env var
34+
/// nor [`dirs::home_dir`] function.
35+
pub fn home_dir() -> PathBuf {
36+
let base = env::var_os("HOME").filter(|oss| !oss.is_empty());
37+
#[cfg(windows)]
38+
let base = base.or_else(|| env::var_os("USERPROFILE").filter(|oss| !oss.is_empty()));
39+
40+
base.map(PathBuf::from)
41+
.unwrap_or_else(|| dirs::home_dir().expect("home directory cannot be determined."))
42+
}
43+
44+
/// (User) Configuration directory to store all our configs.
45+
///
46+
/// Note: This dir will be stored under OS's `config_dir`, which can be:
47+
/// - `$HOME/.config/rim` on Linux
48+
/// - `$HOME/Library/Application Support/rim` on macOS
49+
/// - `$HOME\AppData\Roaming\rim` on Windows
50+
///
51+
/// # Panic
52+
/// Panic if the OS's config directory cannot be determined, which typically meaning
53+
/// that the `HOME` env var is missing and the current OS is not support by the [`dirs`] crate.
54+
pub fn rim_config_dir() -> &'static Path {
55+
get_path_and_create!(RIM_CONFIG_DIR, {
56+
let mut config_root = home_dir();
57+
58+
cfg_if::cfg_if! {
59+
if #[cfg(target_os = "linux")] {
60+
config_root.push(".config")
61+
} else if #[cfg(windows)] {
62+
config_root.push("AppData");
63+
config_root.push("Roaming");
64+
} else if #[cfg(target_os = "macos")] {
65+
config_root.push("Library");
66+
config_root.push("Application Support");
67+
} else {
68+
// fallback to directly use `dir::config_dir`.
69+
// The reason we not directly using it was because we can
70+
// support mocked test on Windows by setting the `HOME` env var.
71+
dirs::config_dir().expect(
72+
"unable to determine config directory, maybe your OS is not supported"
73+
);
74+
}
75+
}
76+
config_root.push("rim");
77+
config_root
78+
})
79+
}

rim_common/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ extern crate log;
33
#[macro_use]
44
extern crate rust_i18n;
55

6+
pub mod dirs;
67
pub mod types;
78
pub mod utils;
9+
pub mod version_info;
810

911
use types::BuildConfig;
1012

rim_common/src/utils/file_system.rs

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,6 @@ use std::path::{Component, Path, PathBuf};
77
use std::time::Duration;
88
use tempfile::NamedTempFile;
99

10-
/// Get a path to user's "home" directory.
11-
///
12-
/// The home directory is determined by a combination of ways
13-
/// with a fallback order:
14-
///
15-
/// 1. The `HOME` environment variable
16-
/// 2. The `USERPROFILE` environment variable (Windows only)
17-
/// 3. The [`home_dir`](dirs::home_dir) function of the `dirs` crate
18-
///
19-
/// # Panic
20-
///
21-
/// Will panic if such directory cannot be determined,
22-
/// which could be the result of missing certain environment variable at runtime,
23-
/// check [`dirs::home_dir`] for more information.
24-
pub fn home_dir() -> PathBuf {
25-
let base = env::var_os("HOME").filter(|oss| !oss.is_empty());
26-
#[cfg(windows)]
27-
let base = base.or_else(|| env::var_os("USERPROFILE").filter(|oss| !oss.is_empty()));
28-
29-
base.map(PathBuf::from)
30-
.unwrap_or_else(|| dirs::home_dir().expect("home directory cannot be determined."))
31-
}
32-
3310
/// Wrapper to [`std::fs::read_to_string`] but with additional error context.
3411
pub fn read_to_string<P: AsRef<Path>>(name: &str, path: P) -> Result<String> {
3512
fs::read_to_string(path.as_ref()).with_context(|| {

rim_common/src/utils/process.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
33
use std::process::{Command, ExitStatus};
44
use std::{env, io};
55

6-
use anyhow::{bail, Result};
6+
use anyhow::{bail, Context, Result};
77

88
use super::set_exec_permission;
99

@@ -90,6 +90,20 @@ pub fn execute(cmd: Command) -> Result<()> {
9090
execute_command(cmd, true, true).map(|_| ())
9191
}
9292

93+
/// Covenient function to execute a command to finish then collect its output.
94+
pub fn command_output(mut cmd: Command) -> Result<String> {
95+
let inner_ = |cmd: &mut Command| -> Result<String> {
96+
let output = cmd.output()?;
97+
if !output.status.success() {
98+
bail!("{}", String::from_utf8_lossy(&output.stderr));
99+
}
100+
Ok(String::from_utf8_lossy(&output.stdout).trim().into())
101+
};
102+
103+
inner_(&mut cmd)
104+
.with_context(|| format!("failed when executing command: {}", cmd_to_string(cmd)))
105+
}
106+
93107
/// Execute a command.
94108
///
95109
/// - When `expect_success` is `true`,

rim_common/src/version_info.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
//! Retrieve detailed version information with the help of `git`
2+
//!
3+
//! (Inspired by clippy's [`rustc_tools_utils` crate](https://crates.io/crates/rustc_tools_util))
4+
5+
use std::path::PathBuf;
6+
7+
use crate::{cmd, utils::command_output};
8+
9+
/// Get version string that includes git commit information.
10+
#[macro_export]
11+
macro_rules! get_version_info {
12+
() => {{
13+
let version = std::option_env!("TAG_VERSION").unwrap_or(std::env!("CARGO_PKG_VERSION"));
14+
let commit_hash = std::option_env!("GIT_HASH");
15+
let commit_date = std::option_env!("COMMIT_DATE");
16+
17+
if let (Some(hash), Some(date)) = (commit_hash, commit_date) {
18+
std::format!("{version} ({} {})", hash.trim(), date.trim())
19+
} else {
20+
version.to_string()
21+
}
22+
}};
23+
}
24+
25+
#[macro_export]
26+
macro_rules! setup_version_info {
27+
() => {{
28+
$crate::version_info::rerun_if_git_changes();
29+
if let Some(hash_) = $crate::version_info::git_commit_hash() {
30+
println!("cargo:rustc-env=GIT_HASH={hash_}");
31+
}
32+
if let Some(date_) = $crate::version_info::git_commit_date() {
33+
println!("cargo:rustc-env=COMMIT_DATE={date_}");
34+
}
35+
if let Some(tag_) = $crate::version_info::git_tag_as_version() {
36+
println!("cargo:rustc-env=TAG_VERSION={tag_}");
37+
}
38+
}};
39+
}
40+
41+
pub fn rerun_if_git_changes() {
42+
let Ok(git_head_file) =
43+
command_output(cmd!("git", "rev-parse", "--git-path", "HEAD")).map(PathBuf::from)
44+
else {
45+
return;
46+
};
47+
if git_head_file.exists() {
48+
println!("cargo::rerun-if-changed={}", git_head_file.display());
49+
}
50+
51+
let Ok(git_head_ref_file) = command_output(cmd!("git", "symbolic-ref", "-q", "HEAD"))
52+
.and_then(|head_ref| command_output(cmd!("git", "rev-parse", "--git-path", &head_ref)))
53+
.map(PathBuf::from)
54+
else {
55+
return;
56+
};
57+
if git_head_ref_file.exists() {
58+
println!("cargo::rerun-if-changed={}", git_head_ref_file.display());
59+
}
60+
}
61+
62+
/// Getting git tag name if that exists.
63+
pub fn git_tag_as_version() -> Option<String> {
64+
let raw = command_output(cmd!("git", "describe", "--exact-match", "--tags")).ok()?;
65+
// remove the leading `v`
66+
Some(raw.trim_start_matches('v').into())
67+
}
68+
69+
pub fn git_commit_hash() -> Option<String> {
70+
command_output(cmd!("git", "rev-parse", "--short", "HEAD")).ok()
71+
}
72+
73+
pub fn git_commit_date() -> Option<String> {
74+
command_output(cmd!(
75+
"git",
76+
"log",
77+
"-1",
78+
"--date=short",
79+
"--pretty=format:%cd"
80+
))
81+
.ok()
82+
}

0 commit comments

Comments
 (0)