failed attempt at making a single binary for CLI and GUI on Windows
This commit is contained in:
parent
5b9c711008
commit
4ee1d543f7
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "creddy",
|
"name": "creddy",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
|
95
src-tauri/Cargo.lock
generated
95
src-tauri/Cargo.lock
generated
@ -68,36 +68,6 @@ version = "1.0.71"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "app"
|
|
||||||
version = "0.2.1"
|
|
||||||
dependencies = [
|
|
||||||
"argon2",
|
|
||||||
"auto-launch",
|
|
||||||
"aws-config",
|
|
||||||
"aws-sdk-sts",
|
|
||||||
"aws-smithy-types",
|
|
||||||
"aws-types",
|
|
||||||
"chacha20poly1305",
|
|
||||||
"clap",
|
|
||||||
"dirs 5.0.1",
|
|
||||||
"is-terminal",
|
|
||||||
"netstat2",
|
|
||||||
"once_cell",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"sodiumoxide",
|
|
||||||
"sqlx",
|
|
||||||
"strum",
|
|
||||||
"strum_macros",
|
|
||||||
"sysinfo",
|
|
||||||
"tauri",
|
|
||||||
"tauri-build",
|
|
||||||
"tauri-plugin-single-instance",
|
|
||||||
"thiserror",
|
|
||||||
"tokio",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "argon2"
|
name = "argon2"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@ -975,6 +945,37 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "creddy"
|
||||||
|
version = "0.2.2"
|
||||||
|
dependencies = [
|
||||||
|
"argon2",
|
||||||
|
"auto-launch",
|
||||||
|
"aws-config",
|
||||||
|
"aws-sdk-sts",
|
||||||
|
"aws-smithy-types",
|
||||||
|
"aws-types",
|
||||||
|
"chacha20poly1305",
|
||||||
|
"clap",
|
||||||
|
"dirs 5.0.1",
|
||||||
|
"gag",
|
||||||
|
"netstat2",
|
||||||
|
"once_cell",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"sodiumoxide",
|
||||||
|
"sqlx",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
|
"sysinfo",
|
||||||
|
"tauri",
|
||||||
|
"tauri-build",
|
||||||
|
"tauri-plugin-single-instance",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"windows 0.48.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crossbeam-channel"
|
name = "crossbeam-channel"
|
||||||
version = "0.5.8"
|
version = "0.5.8"
|
||||||
@ -1347,6 +1348,17 @@ dependencies = [
|
|||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "filedescriptor"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"thiserror",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "filetime"
|
name = "filetime"
|
||||||
version = "0.2.21"
|
version = "0.2.21"
|
||||||
@ -1529,6 +1541,16 @@ dependencies = [
|
|||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gag"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a713bee13966e9fbffdf7193af71d54a6b35a0bb34997cd6c9519ebeb5005972"
|
||||||
|
dependencies = [
|
||||||
|
"filedescriptor",
|
||||||
|
"tempfile",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gdk"
|
name = "gdk"
|
||||||
version = "0.15.4"
|
version = "0.15.4"
|
||||||
@ -2099,18 +2121,6 @@ dependencies = [
|
|||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "is-terminal"
|
|
||||||
version = "0.4.7"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
|
||||||
dependencies = [
|
|
||||||
"hermit-abi 0.3.1",
|
|
||||||
"io-lifetimes",
|
|
||||||
"rustix",
|
|
||||||
"windows-sys 0.48.0",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
@ -4009,6 +4019,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fe7e0f1d535e7cbbbab43c82be4fc992b84f9156c16c160955617e0260ebc449"
|
checksum = "fe7e0f1d535e7cbbbab43c82be4fc992b84f9156c16c160955617e0260ebc449"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"clap",
|
||||||
"cocoa",
|
"cocoa",
|
||||||
"dirs-next",
|
"dirs-next",
|
||||||
"embed_plist",
|
"embed_plist",
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "app"
|
name = "creddy"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
description = "A Tauri App"
|
description = "A friendly AWS credentials manager"
|
||||||
authors = ["you"]
|
authors = ["Joseph Montanaro"]
|
||||||
license = ""
|
license = ""
|
||||||
repository = ""
|
repository = ""
|
||||||
default-run = "app"
|
default-run = "creddy"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
rust-version = "1.57"
|
rust-version = "1.57"
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ tauri-build = { version = "1.0.4", features = [] }
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
tauri = { version = "1.2", features = ["dialog", "os-all", "system-tray"] }
|
tauri = { version = "1.2", features = ["cli", "dialog", "os-all", "system-tray"] }
|
||||||
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
|
tauri-plugin-single-instance = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "dev" }
|
||||||
sodiumoxide = "0.2.7"
|
sodiumoxide = "0.2.7"
|
||||||
tokio = { version = ">=1.19", features = ["full"] }
|
tokio = { version = ">=1.19", features = ["full"] }
|
||||||
@ -35,9 +35,11 @@ strum_macros = "0.24"
|
|||||||
auto-launch = "0.4.0"
|
auto-launch = "0.4.0"
|
||||||
dirs = "5.0"
|
dirs = "5.0"
|
||||||
clap = { version = "3.2.23", features = ["derive"] }
|
clap = { version = "3.2.23", features = ["derive"] }
|
||||||
is-terminal = "0.4.7"
|
# is-terminal = "0.4.7"
|
||||||
argon2 = { version = "0.5.0", features = ["std"] }
|
argon2 = { version = "0.5.0", features = ["std"] }
|
||||||
chacha20poly1305 = { version = "0.10.1", features = ["std"] }
|
chacha20poly1305 = { version = "0.10.1", features = ["std"] }
|
||||||
|
windows = { version = "0.48", features = ["Win32_Foundation", "Win32_System_Console"] }
|
||||||
|
gag = "1.0"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# by default Tauri runs in production mode
|
# by default Tauri runs in production mode
|
||||||
|
@ -13,7 +13,6 @@ use tokio::{
|
|||||||
io::{AsyncReadExt, AsyncWriteExt},
|
io::{AsyncReadExt, AsyncWriteExt},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
use crate::app;
|
use crate::app;
|
||||||
use crate::config::AppConfig;
|
use crate::config::AppConfig;
|
||||||
use crate::credentials::{BaseCredentials, SessionCredentials};
|
use crate::credentials::{BaseCredentials, SessionCredentials};
|
||||||
@ -23,6 +22,16 @@ use crate::errors::*;
|
|||||||
pub fn parser() -> Command<'static> {
|
pub fn parser() -> Command<'static> {
|
||||||
Command::new("creddy")
|
Command::new("creddy")
|
||||||
.about("A friendly AWS credentials manager")
|
.about("A friendly AWS credentials manager")
|
||||||
|
// we don't want the default help handling because it early-exits,
|
||||||
|
// and on Windows we need to setup the console before we can output
|
||||||
|
.disable_help_flag(true)
|
||||||
|
.arg(
|
||||||
|
Arg::new("help")
|
||||||
|
.short('h')
|
||||||
|
.long("help")
|
||||||
|
.action(ArgAction::SetTrue)
|
||||||
|
.help("Print this message or the help of the given subcommand(s)")
|
||||||
|
)
|
||||||
.subcommand(
|
.subcommand(
|
||||||
Command::new("run")
|
Command::new("run")
|
||||||
.about("Launch Creddy")
|
.about("Launch Creddy")
|
||||||
|
@ -2,7 +2,6 @@ use std::net::Ipv4Addr;
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use auto_launch::AutoLaunchBuilder;
|
use auto_launch::AutoLaunchBuilder;
|
||||||
use is_terminal::IsTerminal;
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use sqlx::SqlitePool;
|
use sqlx::SqlitePool;
|
||||||
|
|
||||||
@ -96,7 +95,7 @@ pub fn get_or_create_db_path() -> Result<PathBuf, DataDirError> {
|
|||||||
path.push("Creddy");
|
path.push("Creddy");
|
||||||
|
|
||||||
std::fs::create_dir_all(&path)?;
|
std::fs::create_dir_all(&path)?;
|
||||||
if cfg!(debug_assertions) && std::io::stdout().is_terminal() {
|
if cfg!(debug_assertions) {
|
||||||
path.push("creddy.dev.db");
|
path.push("creddy.dev.db");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3,6 +3,20 @@
|
|||||||
windows_subsystem = "windows"
|
windows_subsystem = "windows"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
use {
|
||||||
|
std::fs::File,
|
||||||
|
std::os::windows::io::FromRawHandle,
|
||||||
|
std::os::raw::c_void,
|
||||||
|
gag::Redirect,
|
||||||
|
windows::Win32::System::Console::{
|
||||||
|
AllocConsole,
|
||||||
|
AttachConsole,
|
||||||
|
GetStdHandle,
|
||||||
|
STD_OUTPUT_HANDLE,
|
||||||
|
STD_ERROR_HANDLE,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
mod app;
|
mod app;
|
||||||
mod cli;
|
mod cli;
|
||||||
@ -15,18 +29,40 @@ mod state;
|
|||||||
mod server;
|
mod server;
|
||||||
mod tray;
|
mod tray;
|
||||||
|
|
||||||
|
|
||||||
use crate::errors::ErrorPopup;
|
use crate::errors::ErrorPopup;
|
||||||
|
|
||||||
|
use std::io::Write;
|
||||||
fn main() {
|
fn main() {
|
||||||
let res = match cli::parser().get_matches().subcommand() {
|
let args = cli::parser().get_matches();
|
||||||
None | Some(("run", _)) => {
|
let help = matches!(args.get_one::<bool>("help"), Some(true));
|
||||||
|
|
||||||
|
// This is the only case that doesn't need a console
|
||||||
|
if let None | Some(("run", _)) = args.subcommand() {
|
||||||
|
if !help {
|
||||||
app::run().error_popup("Creddy failed to start");
|
app::run().error_popup("Creddy failed to start");
|
||||||
Ok(())
|
return;
|
||||||
},
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// on Windows, need to do the whole allocate-a-console thing
|
||||||
|
#[cfg(windows)]
|
||||||
|
attach_console();
|
||||||
|
// let (out, err) = setup_console();
|
||||||
|
println!("Testing stdout");
|
||||||
|
// writeln!(&mut out, "Testing allocated file");
|
||||||
|
|
||||||
|
if help {
|
||||||
|
// if we can't print help, we can't print an error, so just panic
|
||||||
|
dbg!(args.get_one::<bool>("help"));
|
||||||
|
cli::parser().print_help().unwrap();
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let res = match args.subcommand() {
|
||||||
Some(("show", m)) => cli::show(m),
|
Some(("show", m)) => cli::show(m),
|
||||||
Some(("exec", m)) => cli::exec(m),
|
Some(("exec", m)) => cli::exec(m),
|
||||||
|
// clap ensures that subcommand is either None or run/show/exec
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -34,3 +70,43 @@ fn main() {
|
|||||||
eprintln!("Error: {e}");
|
eprintln!("Error: {e}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn attach_console() {
|
||||||
|
unsafe { AttachConsole(u32::MAX); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
fn setup_console() -> (Redirect<File>, Redirect<File>) {
|
||||||
|
let (mut stdout, stderr) = unsafe {
|
||||||
|
AllocConsole();
|
||||||
|
// if we can't get handles to stdout/err, we can't display these errors,
|
||||||
|
// so there's no point in doing anything other than panicking
|
||||||
|
let stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE).unwrap();
|
||||||
|
let stderr_handle = GetStdHandle(STD_ERROR_HANDLE).unwrap();
|
||||||
|
|
||||||
|
let mut f = File::create("C:\\Users\\Joe\\Downloads\\debug.txt").unwrap();
|
||||||
|
writeln!(&mut f, "{stdout_handle:?}\n{:?}", stdout_handle.0 as *mut c_void).unwrap();
|
||||||
|
|
||||||
|
(
|
||||||
|
File::from_raw_handle(stdout_handle.0 as *mut c_void),
|
||||||
|
File::from_raw_handle(stderr_handle.0 as *mut c_void),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
writeln!(&mut stdout, "Testing stdout before redirect")
|
||||||
|
.map_err(|e| log_err(e))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
(
|
||||||
|
Redirect::stdout(stdout).unwrap(),
|
||||||
|
Redirect::stderr(stderr).unwrap()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn log_err(e: impl std::error::Error) {
|
||||||
|
let mut f = File::create("C:\\Users\\Joe\\Downloads\\log.txt").unwrap();
|
||||||
|
writeln!(&mut f, "{e}").unwrap();
|
||||||
|
}
|
||||||
|
@ -7,8 +7,8 @@
|
|||||||
"distDir": "../dist"
|
"distDir": "../dist"
|
||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "creddy",
|
"productName": "Creddy",
|
||||||
"version": "0.2.1"
|
"version": "0.2.2"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
@ -47,6 +47,14 @@
|
|||||||
"timestampUrl": ""
|
"timestampUrl": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cli": {
|
||||||
|
"description": "A friendly AWS credentials manager",
|
||||||
|
"subcommands": {
|
||||||
|
"run": {
|
||||||
|
"description": "Launch Creddy"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"csp": {
|
"csp": {
|
||||||
"default-src": ["'self'"],
|
"default-src": ["'self'"],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user