This commit is contained in:
hinto-janaiyo 2022-11-21 21:01:50 -05:00
parent e8a01e71b9
commit 20c7542189
No known key found for this signature in database
GPG key ID: B1C5A64B80691E45
9 changed files with 164 additions and 104 deletions

View file

@ -1,29 +1,40 @@
## v0.2.0 ## v0.5.0
## Prototype Release ## Prototype Release
* Added `Simple` P2Pool tab: * Added `Simple` P2Pool tab:
- Monero address input with valid address check (base58 regex) - Monero address input with valid address check (base58 regex)
- [Community Monero node selector](https://github.com/hinto-janaiyo/gupax/tree/main/README.md#community-monero-nodes) - [Community Monero node selector](https://github.com/hinto-janaiyo/gupax/tree/main/README.md#community-monero-nodes)
- Community node ping button (asynchronous `JSON-RPC` calls to all nodes) - Community node ping button (asynchronous `JSON-RPC` calls to all nodes)
- `<300ms = GREEN` - Color coded list after ping:
- `<1000ms = YELLOW` ```
- `<5000ms = RED` <300ms = GREEN
- `>5000ms = BLACK` <1000ms = YELLOW
<5000ms = RED
>5000ms = BLACK
```
- `Auto-select` - Pick the fastest node after ping automatically - `Auto-select` - Pick the fastest node after ping automatically
- `Auto-ping` - Automatically ping nodes on Gupax startup - `Auto-ping` - Automatically ping nodes on Gupax startup
* Added `Advanced` P2Pool tab: * Added `Advanced` P2Pool tab:
- Manual node database, select/add/edit/delete a custom `Name/IP/RPC/ZMQ` (max 1000 nodes), saved at:
- Windows: `C:\Users\USER\AppData\Roaming\Gupax\node.toml`
- macOS: `/Users/USER/Library/Application Support/Gupax/node.toml`
- Linux: `/home/USER/.local/share/gupax/node.toml`
- Overriding command arguments to P2Pool - Overriding command arguments to P2Pool
- Manual node database, select/add/delete a custom `Name/IP/RPC/ZMQ` (max 1000 nodes)
- P2Pool main/mini toggle - P2Pool main/mini toggle
- Out/In Peers slider - Out/In Peers slider
- Log level slider - Log level slider
* Added command arguments: * Added command arguments:
- `-h | --help Print this help message` ```
- `-v | --version Print version and build info` --help Print this help message
- `-l | --node-list Print the manual node list` --version Print version and build info
- `-s | --state Print Gupax state` --state Print Gupax state
- `-n | --no-startup Disable all auto-startup settings for this instance` --nodes Print the manual node list
- `-r | --reset Reset all Gupax state and the manual node list` --no-startup Disable all auto-startup settings for this instance
- `-f | --ferris Print an extremely cute crab` --reset-state Reset all Gupax state (your settings)
--reset-nodes Reset the manual node list in the [P2Pool] tab
--reset-all Reset both the state and the manual node list
--ferris Print an extremely cute crab
```
* Added fullscreen GUI error handler (Error message + UI buttons for response, Yes/No, Quit, etc)
* Added a native `File Explorer/Finder/GTK` file selector for picking P2Pool/XMRig binary path in `Gupax` tab * Added a native `File Explorer/Finder/GTK` file selector for picking P2Pool/XMRig binary path in `Gupax` tab
* Added detailed console log levels `RUST_LOG=(trace|debug|info|warn|error) ./gupax` * Added detailed console log levels `RUST_LOG=(trace|debug|info|warn|error) ./gupax`
* [Added new PGP key](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc) * [Added new PGP key](https://github.com/hinto-janaiyo/gupax/blob/main/pgp/hinto-janaiyo.asc)

102
Cargo.lock generated
View file

@ -2,6 +2,43 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "Gupax"
version = "0.5.0"
dependencies = [
"anyhow",
"arti-client",
"arti-hyper",
"bytes",
"dirs",
"eframe",
"egui",
"egui_extras",
"env_logger 0.9.3",
"figment",
"flate2",
"hyper",
"hyper-tls",
"image",
"log",
"num-format",
"num_cpus",
"rand 0.8.5",
"regex",
"rfd",
"serde",
"serde_json",
"tar",
"tls-api",
"tls-api-native-tls",
"tokio",
"toml",
"tor-rtcompat",
"walkdir",
"winres",
"zip",
]
[[package]] [[package]]
name = "ab_glyph" name = "ab_glyph"
version = "0.2.18" version = "0.2.18"
@ -82,9 +119,9 @@ dependencies = [
[[package]] [[package]]
name = "aho-corasick" name = "aho-corasick"
version = "0.7.19" version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e" checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@ -730,9 +767,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.12" version = "0.9.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96bf8df95e795db1a4aca2957ad884a2df35413b24bbeb3114422f3cc21498e8" checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"cfg-if", "cfg-if",
@ -743,9 +780,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.7" version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebb3d1683412e9be6a15533314f00ec223c0762c522a3f77f048b265aab4470c" checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -753,9 +790,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.13" version = "0.8.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "422f23e724af1240ec469ea1e834d87a4b59ce2efe2c6a96256b0c47e2fd86aa" checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@ -1785,43 +1822,6 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "gupax"
version = "0.2.0"
dependencies = [
"anyhow",
"arti-client",
"arti-hyper",
"bytes",
"dirs",
"eframe",
"egui",
"egui_extras",
"env_logger 0.9.3",
"figment",
"flate2",
"hyper",
"hyper-tls",
"image",
"log",
"num-format",
"num_cpus",
"rand 0.8.5",
"regex",
"rfd",
"serde",
"serde_json",
"tar",
"tls-api",
"tls-api-native-tls",
"tokio",
"toml",
"tor-rtcompat",
"walkdir",
"winres",
"zip",
]
[[package]] [[package]]
name = "half" name = "half"
version = "2.1.0" version = "2.1.0"
@ -2342,7 +2342,7 @@ checksum = "451422b7e4718271c8b5b3aadf5adedba43dc76312454b387e98fae0fc951aa0"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"jni-sys", "jni-sys",
"ndk-sys 0.4.0+25.0.8775105", "ndk-sys 0.4.0",
"num_enum", "num_enum",
"raw-window-handle 0.5.0", "raw-window-handle 0.5.0",
"thiserror", "thiserror",
@ -2380,7 +2380,7 @@ dependencies = [
"ndk 0.7.0", "ndk 0.7.0",
"ndk-context", "ndk-context",
"ndk-macro", "ndk-macro",
"ndk-sys 0.4.0+25.0.8775105", "ndk-sys 0.4.0",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
] ]
@ -2409,9 +2409,9 @@ dependencies = [
[[package]] [[package]]
name = "ndk-sys" name = "ndk-sys"
version = "0.4.0+25.0.8775105" version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f74ddd54b7da8d38d399faf43472ac9759f1a028a45c83154bff603e0f56385a" checksum = "21d83ec9c63ec5bf950200a8e508bdad6659972187b625469f58ef8c08e29046"
dependencies = [ dependencies = [
"jni-sys", "jni-sys",
] ]
@ -3388,9 +3388,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.88" version = "1.0.89"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e8b3801309262e8184d9687fb697586833e939767aea0dda89f5a8e650e8bd7" checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",

View file

@ -1,6 +1,6 @@
[package] [package]
name = "gupax" name = "Gupax"
version = "0.2.0" version = "0.5.0"
authors = ["hinto-janaiyo <hinto.janaiyo@protonmail.com>"] authors = ["hinto-janaiyo <hinto.janaiyo@protonmail.com>"]
description = "GUI for P2Pool+XMRig" description = "GUI for P2Pool+XMRig"
documentation = "https://github.com/hinto-janaiyo/gupax" documentation = "https://github.com/hinto-janaiyo/gupax"

View file

@ -1,25 +1,27 @@
# Gupax source files # Gupax source files
* [Structure](#Structure) * [Structure](#Structure)
* [Bootstrap](#Bootstrap) * [Bootstrap](#Bootstrap)
* [State](#State) * [Disk](#Disk)
* [Scale](#Scale) * [Scale](#Scale)
* [Naming Scheme](#naming-scheme)
## Structure ## Structure
| File/Folder | Purpose | | File/Folder | Purpose |
|----------------|---------| |--------------|---------|
| `constants.rs` | General constants needed in Gupax | constants.rs | General constants needed in Gupax
| `disk.rs` | Code for writing to disk: `state.toml`, `node.toml`; This holds the structs for mutable [State] | command.rs | Code for executing/handling P2Pool/XMRig
| `ferris.rs` | Cute crab bytes | disk.rs | Code for writing to disk: `state.toml`, `node.toml`; This holds the structs for mutable [State]
| `gupax.rs` | `Gupax` tab | ferris.rs | Cute crab bytes
| `main.rs` | `App/Tab/State` + misc data/functions | gupax.rs | `Gupax` tab
| `node.rs` | Community node ping code for the `P2Pool` simple tab | main.rs | `App/Tab/State` + misc data/functions
| `p2pool.rs` | `P2Pool` tab | node.rs | Community node ping code for the `P2Pool` simple tab
| `status.rs` | `Status` tab | p2pool.rs | `P2Pool` tab
| `update.rs` | Update code for the `Gupax` tab | status.rs | `Status` tab
| `xmrig.rs` | `XMRig` tab | update.rs | Update code for the `Gupax` tab
| xmrig.rs | `XMRig` tab
## Bootstrap ## Bootstrap
This is how Gupax works internally when starting up, divided into 3 sections. This is how Gupax works internally when starting up:
1. **INIT** 1. **INIT**
- Initialize custom console logging with `log`, `env_logger` - Initialize custom console logging with `log`, `env_logger`
@ -41,14 +43,20 @@ This is how Gupax works internally when starting up, divided into 3 sections.
- If `ask_before_quit` == `true`, ask before quitting - If `ask_before_quit` == `true`, ask before quitting
- Kill processes, kill connections, exit - Kill processes, kill connections, exit
## State ## Disk
Internal state is saved in the "OS data folder" as `state.toml`, using the [TOML](https://github.com/toml-lang/toml) format. If not found, a default `state.toml` file will be created. Given a slightly corrupted state file, Gupax will attempt to merge it with a new default one. This will most likely happen if the internal data structure of `state.toml` is changed in the future (e.g removing an outdated setting). Merging silently in the background is a good non-interactive way to handle this. If Gupax can't read/write to disk at all, or if there are any other big issues, it will show an un-recoverable error window. Long-term state is saved onto the disk in the "OS data folder", using the [TOML](https://github.com/toml-lang/toml) format. If not found, default files will be created. Given a slightly corrupted state file, Gupax will attempt to merge it with a new default one. This will most likely happen if the internal data structure of `state.toml` is changed in the future (e.g removing an outdated setting). Merging silently in the background is a good non-interactive way to handle this. If Gupax can't read/write to disk at all, or if there are any other big issues, it will show an un-recoverable error window.
| OS | Data Folder | Example | | OS | Data Folder | Example |
|----------|----------------------------------------- |-----------------------------------------------------------| |----------|----------------------------------------- |------------------------------------------------|
| Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Roaming\Gupax\gupax.toml | | Windows | `{FOLDERID_LocalAppData}` | C:\Users\Alice\AppData\Roaming\Gupax |
| macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support/Gupax/gupax.toml | | macOS | `$HOME`/Library/Application Support | /Users/Alice/Library/Application Support/Gupax |
| Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share/gupax/gupax.toml | | Linux | `$XDG_DATA_HOME` or `$HOME`/.local/share | /home/alice/.local/share/gupax |
The current files saved to disk:
* `state.toml` Gupax state/settings
* `node.toml` The manual node database used for P2Pool advanced
Arti (Tor) also needs to save cache and state. It uses the same file/folder conventions (.local/arti, .cache/arti).
## Scale ## Scale
Every frame, the max available `[width, height]` are calculated, and those are used as a baseline for the Top/Bottom bars, containing the tabs and status bar. After that, all available space is given to the middle ui elements. The scale is calculated every frame so that all elements can scale immediately as the user adjusts it; this doesn't take as much CPU as you might think since frames are only rendered on user interaction. Some elements are subtracted a fixed number because the `ui.seperator()`s add some fixed space which needs to be accounted for. Every frame, the max available `[width, height]` are calculated, and those are used as a baseline for the Top/Bottom bars, containing the tabs and status bar. After that, all available space is given to the middle ui elements. The scale is calculated every frame so that all elements can scale immediately as the user adjusts it; this doesn't take as much CPU as you might think since frames are only rendered on user interaction. Some elements are subtracted a fixed number because the `ui.seperator()`s add some fixed space which needs to be accounted for.
@ -59,3 +67,26 @@ Main [App] outer frame (default: [1280.0, 720.0])
├─ BottomPanel = height: 1/20th ├─ BottomPanel = height: 1/20th
├─ CentralPanel = height: the rest ├─ CentralPanel = height: the rest
``` ```
## Naming Scheme
This is the internal naming scheme used by Gupax when updating/creating default folders/etc:
Windows:
- Gupax: `Gupax.exe`
- P2Pool: `P2Pool\p2pool.exe`
- XMRig: `XMRig\xmrig.exe`
macOS:
- Gupax: `Gupax.app/.../Gupax` (Gupax is packaged as an `.app` on macOS)
- P2Pool: `p2pool/p2pool`
- XMRig: `xmrig/xmrig`
Linux:
- Gupax: `gupax`
- P2Pool: `p2pool/p2pool`
- XMRig: `xmrig/xmrig`
These have to be packaged exactly with these names because the update code is case-sensitive. If an exact match is not found, it will error.
For the Gupax data folder:
- Windows: `Gupax`
- macOS: `Gupax`
- Linux: `gupax`

View file

@ -16,7 +16,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
// Hide console in Windows // Hide console in Windows
//#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
//---------------------------------------------------------------------------------------------------- Imports //---------------------------------------------------------------------------------------------------- Imports
// egui/eframe // egui/eframe
@ -238,6 +238,9 @@ impl App {
let xmrig_path = og.gupax.absolute_xmrig_path.clone(); let xmrig_path = og.gupax.absolute_xmrig_path.clone();
let tor = og.gupax.update_via_tor; let tor = og.gupax.update_via_tor;
app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor))); app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor)));
// Set state version as compiled in version
og.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
app.state.version.lock().unwrap().gupax = GUPAX_VERSION.to_string();
drop(og); // Unlock [og] drop(og); // Unlock [og]
info!("App ... OK"); info!("App ... OK");
app app
@ -409,7 +412,7 @@ fn init_logger(now: Instant) {
buf, buf,
"[{}] [{}] [{}:{}] {}", "[{}] [{}] [{}:{}] {}",
style.set_bold(true).value(level), style.set_bold(true).value(level),
buf.style().set_dimmed(true).value(format!("{:.7}", now.elapsed().as_secs_f32())), buf.style().set_dimmed(true).value(format!("{:.3}", now.elapsed().as_secs_f32())),
buf.style().set_dimmed(true).value(record.file().unwrap_or("???")), buf.style().set_dimmed(true).value(record.file().unwrap_or("???")),
buf.style().set_dimmed(true).value(record.line().unwrap_or(0)), buf.style().set_dimmed(true).value(record.line().unwrap_or(0)),
record.args(), record.args(),

View file

@ -337,7 +337,7 @@ impl P2pool {
zmq: self.zmq.clone(), zmq: self.zmq.clone(),
}; };
node_vec.push((self.name.clone(), node)); node_vec.push((self.name.clone(), node));
self.selected_index = (node_vec_len); self.selected_index = node_vec_len;
self.selected_name = self.name.clone(); self.selected_name = self.name.clone();
self.selected_ip = self.ip.clone(); self.selected_ip = self.ip.clone();
self.selected_rpc = self.rpc.clone(); self.selected_rpc = self.rpc.clone();

View file

@ -39,7 +39,7 @@ use log::*;
use rand::distributions::Alphanumeric; use rand::distributions::Alphanumeric;
use rand::{thread_rng, Rng}; use rand::{thread_rng, Rng};
use serde::{Serialize,Deserialize}; use serde::{Serialize,Deserialize};
use std::path::PathBuf; use std::path::{Path,PathBuf};
use std::sync::{Arc,Mutex}; use std::sync::{Arc,Mutex};
use tls_api::{TlsConnector, TlsConnectorBuilder}; use tls_api::{TlsConnector, TlsConnectorBuilder};
use tokio::task::JoinHandle; use tokio::task::JoinHandle;
@ -102,8 +102,10 @@ const P2POOL_EXTENSION: &'static str = "-linux-x64.tar.gz";
const XMRIG_EXTENSION: &'static str = "-linux-static-x64.tar.gz"; const XMRIG_EXTENSION: &'static str = "-linux-static-x64.tar.gz";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
const GUPAX_BINARY: &'static str = "gupax.exe"; const GUPAX_BINARY: &'static str = "Gupax.exe";
#[cfg(target_family = "unix")] #[cfg(target_os = "macos")]
const GUPAX_BINARY: &'static str = "Gupax";
#[cfg(target_os = "linux")]
const GUPAX_BINARY: &'static str = "gupax"; const GUPAX_BINARY: &'static str = "gupax";
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
@ -554,7 +556,9 @@ impl Update {
// 3b. Gupax version is builtin to binary, so no state change needed // 3b. Gupax version is builtin to binary, so no state change needed
*update.lock().unwrap().msg.lock().unwrap() = format!("{}{}", MSG_UPGRADE, new_pkgs); *update.lock().unwrap().msg.lock().unwrap() = format!("{}{}", MSG_UPGRADE, new_pkgs);
info!("Update | {}", UPGRADE); info!("Update | {}", UPGRADE);
// Just in case, create all folders // If this bool doesn't get set, something has gone wrong because
// we _didn't_ find a binary even though we downloaded it.
let mut found = false;
for entry in WalkDir::new(tmp_dir.clone()) { for entry in WalkDir::new(tmp_dir.clone()) {
let entry = entry?.clone(); let entry = entry?.clone();
// If not a file, continue // If not a file, continue
@ -562,6 +566,7 @@ impl Update {
let basename = entry.file_name().to_str().ok_or(anyhow::Error::msg("WalkDir basename failed"))?; let basename = entry.file_name().to_str().ok_or(anyhow::Error::msg("WalkDir basename failed"))?;
match basename { match basename {
GUPAX_BINARY|P2POOL_BINARY|XMRIG_BINARY => { GUPAX_BINARY|P2POOL_BINARY|XMRIG_BINARY => {
found = true;
let name = match basename { let name = match basename {
GUPAX_BINARY => Gupax, GUPAX_BINARY => Gupax,
P2POOL_BINARY => P2pool, P2POOL_BINARY => P2pool,
@ -572,22 +577,23 @@ impl Update {
P2pool => update.lock().unwrap().path_p2pool.clone(), P2pool => update.lock().unwrap().path_p2pool.clone(),
Xmrig => update.lock().unwrap().path_xmrig.clone(), Xmrig => update.lock().unwrap().path_xmrig.clone(),
}; };
let path = Path::new(&path);
// Unix can replace running binaries no problem (they're loaded into memory) // Unix can replace running binaries no problem (they're loaded into memory)
// Windows locks binaries in place, so we must move (rename) current binary // Windows locks binaries in place, so we must move (rename) current binary
// into the temp folder, then move the new binary into the old ones spot. // into the temp folder, then move the new binary into the old ones spot.
// Clearing the temp folder is now moved at startup instead at the end // Clearing the temp folder is now moved at startup instead at the end
// of this function due to this behavior, thanks Windows. // of this function due to this behavior, thanks Windows.
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
if path.exists() {
let tmp_windows = match name { let tmp_windows = match name {
Gupax => tmp_dir.clone() + "gupax_old.exe", Gupax => tmp_dir.clone() + "gupax_old.exe",
P2pool => tmp_dir.clone() + "p2pool_old.exe", P2pool => tmp_dir.clone() + "p2pool_old.exe",
Xmrig => tmp_dir.clone() + "xmrig_old.exe", Xmrig => tmp_dir.clone() + "xmrig_old.exe",
}; };
#[cfg(target_os = "windows")] info!("Update | WINDOWS ONLY ... Moving old [{}] -> [{}]", path.display(), tmp_windows);
info!("Update | WINDOWS ONLY ... Moving [{}] -> [{}]", &path, tmp_windows);
#[cfg(target_os = "windows")]
std::fs::rename(&path, tmp_windows)?; std::fs::rename(&path, tmp_windows)?;
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path); }
info!("Update | Moving new [{}] -> [{}]", entry.path().display(), path.display());
if name == P2pool || name == Xmrig { if name == P2pool || name == Xmrig {
std::fs::create_dir_all(std::path::Path::new(&path).parent().ok_or(anyhow::Error::msg(format!("{} path failed", name)))?)?; std::fs::create_dir_all(std::path::Path::new(&path).parent().ok_or(anyhow::Error::msg(format!("{} path failed", name)))?)?;
} }
@ -602,6 +608,7 @@ impl Update {
_ => (), _ => (),
} }
} }
if found == false { return Err(anyhow::Error::msg("Fatal error: Package binary could not be found")) }
// Remove tmp dir (on Unix) // Remove tmp dir (on Unix)
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]

6
utils/README.md Normal file
View file

@ -0,0 +1,6 @@
## Utilities
| File/Folder | Purpose |
|-------------|---------|
| prepare.sh | Changes version across repo, commits
| skel | A skeleton directory with the proper naming scheme + folder structure for packaging Gupax for all OS's

View file

@ -27,8 +27,10 @@ cat << EOM > CHANGELOG.md.new
## Fixes ## Fixes
* *
--- ---
EOM EOM
cat CHANGELOG.md >> CHANGELOG.md.new cat CHANGELOG.md >> CHANGELOG.md.new
mv -f CHANGELOG.md.new CHANGELOG.md mv -f CHANGELOG.md.new CHANGELOG.md