@smbcloud / cli / commits / 863371d

Refactor networking: move Environment to network crate

- Move `environment.rs` to the new `network` crate and update imports - Remove direct dependency on `smbcloud_networking::environment` - Move token file helpers to `cli::token` module - Update Cargo.toml dependencies and workspace usage - Update project networking modules to use `network::environment::Environment`

Seto Elkahfi committed Jul 26, 2025 at 18:26 UTC 863371d2c4ee36813b14739cfd6e9df2a0824127
35 files changed +95 -100
Cargo.lock
+2 -13
@@ -1190,6 +1190,7 @@ dependencies = [
1190 name = "network"
1191 version = "0.1.0"
1192 dependencies = [
1193 + "clap",
1194 "log",
1195 "reqwest",
1196 "serde",
@@ -1937,18 +1938,7 @@ dependencies = [
1938 name = "smbcloud-networking"
1939 version = "0.3.20"
1940 dependencies = [
1940 - "anyhow",
1941 - "async-trait",
1942 - "clap",
1943 - "dirs",
1944 - "home",
1945 - "log",
1946 - "maybe-async",
1947 - "reqwest",
1948 - "serde",
1949 - "serde_json",
1950 - "smbcloud-model",
1951 - "thiserror 2.0.12",
1941 + "network",
1942 "url-builder",
1943 ]
1944
@@ -1966,7 +1956,6 @@ dependencies = [
1956 "anyhow",
1957 "async-trait",
1958 "dirs",
1969 - "home",
1959 "log",
1960 "maybe-async",
1961 "network",
crates/cli/src/account/forgot/mod.rs
+2 -3
@@ -4,12 +4,11 @@ use crate::{
4 };
5 use anyhow::Result;
6 use dialoguer::{theme::ColorfulTheme, Input, Password};
7 +use network::environment::Environment;
8 use reqwest::{Client, StatusCode};
9 use serde::{Deserialize, Serialize};
10 use smbcloud_model::forgot::{Args, Email, Param, UserUpdatePassword};
10 -use smbcloud_networking::{
11 - constants::PATH_USERS_PASSWORD, environment::Environment, smb_base_url_builder,
12 -};
11 +use smbcloud_networking::{constants::PATH_USERS_PASSWORD, smb_base_url_builder};
12 use smbcloud_utils::email_validation;
13 use spinners::Spinner;
14
crates/cli/src/account/lib.rs
+7 -6
@@ -1,6 +1,8 @@
1 +use crate::token::smb_token_file_path;
2 use anyhow::{anyhow, Result};
3 use console::style;
4 use log::debug;
5 +use network::environment::Environment;
6 use regex::Regex;
7 use reqwest::{Client, Response, StatusCode};
8 use smbcloud_model::account::SmbAuthorization;
@@ -8,8 +10,7 @@ use smbcloud_networking::{
10 constants::{
11 GH_OAUTH_CLIENT_ID, GH_OAUTH_REDIRECT_HOST, GH_OAUTH_REDIRECT_PORT, PATH_AUTHORIZE,
12 },
11 - environment::Environment,
12 - smb_base_url_builder, smb_token_file_path,
13 + smb_base_url_builder,
14 };
15 use spinners::Spinner;
16 use std::{
@@ -105,7 +106,7 @@ fn handle_connection(mut stream: TcpStream, tx: Sender<String>) {
106 <meta charset='utf-8'>
107 <title>Hello!</title>
108 </head>
108 -
109 +
110 <body>
111 <h1>Authenticated!</h1>
112 <p>Back to the terminal console to finish your registration.</p>
@@ -118,17 +119,17 @@ fn handle_connection(mut stream: TcpStream, tx: Sender<String>) {
119 "HTTP/1.1 404 NOT FOUND",
120 "<!DOCTYPE html>
121 <html lang='en'>
121 -
122 +
123 <head>
124 <meta charset='utf-8'>
125 <title>404 Not found</title>
126 </head>
126 -
127 +
128 <body>
129 <h1>Oops!</h1>
130 <p>Sorry, I don't know what you're asking for.</p>
131 </body>
131 -
132 +
133 </html>",
134 )
135 }
crates/cli/src/account/login/process.rs
+1 -1
@@ -10,6 +10,7 @@ use anyhow::{anyhow, Result};
10 use console::style;
11 use dialoguer::{console::Term, theme::ColorfulTheme, Confirm, Input, Password, Select};
12 use log::debug;
13 +use network::environment::Environment;
14 use reqwest::{Client, StatusCode};
15 use smbcloud_model::{
16 account::{ErrorCode, GithubInfo, SmbAuthorization, User},
@@ -22,7 +23,6 @@ use smbcloud_networking::{
23 PATH_LINK_GITHUB_ACCOUNT, PATH_RESEND_CONFIRMATION, PATH_RESET_PASSWORD_INSTRUCTIONS,
24 PATH_USERS_PASSWORD, PATH_USERS_SIGN_IN,
25 },
25 - environment::Environment,
26 smb_base_url_builder,
27 };
28 use smbcloud_utils::email_validation;
crates/cli/src/account/logout/mod.rs
+3 -4
@@ -1,10 +1,9 @@
1 +use crate::token::{get_smb_token, smb_token_file_path};
2 use anyhow::{anyhow, Result};
3 use dialoguer::{theme::ColorfulTheme, Confirm};
4 +use network::environment::Environment;
5 use reqwest::{Client, StatusCode};
4 -use smbcloud_networking::{
5 - constants::PATH_USERS_SIGN_OUT, environment::Environment, get_smb_token, smb_base_url_builder,
6 - smb_token_file_path,
7 -};
6 +use smbcloud_networking::{constants::PATH_USERS_SIGN_OUT, smb_base_url_builder};
7 use spinners::Spinner;
8 use std::fs;
9
crates/cli/src/account/me/mod.rs
+3 -3
@@ -1,14 +1,14 @@
1 use crate::account::lib::is_logged_in;
2 +use crate::token::get_smb_token;
3 use crate::{
4 cli::CommandResult,
5 ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
6 };
7 use anyhow::{anyhow, Result};
8 +use network::environment::Environment;
9 use reqwest::{Client, StatusCode};
10 use smbcloud_model::account::User;
9 -use smbcloud_networking::{
10 - constants::PATH_USERS_ME, environment::Environment, get_smb_token, smb_base_url_builder,
11 -};
11 +use smbcloud_networking::{constants::PATH_USERS_ME, smb_base_url_builder};
12 use spinners::Spinner;
13 use tabled::{Table, Tabled};
14
crates/cli/src/account/mod.rs
+1 -1
@@ -10,7 +10,7 @@ use self::{cli::Commands, forgot::process_forgot, login::process_login, signup::
10 use crate::cli::CommandResult;
11 use anyhow::Result;
12 use logout::process_logout;
13 -use smbcloud_networking::environment::Environment;
13 +use network::environment::Environment;
14
15 pub async fn process_account(env: Environment, commands: Commands) -> Result<CommandResult> {
16 match commands {
crates/cli/src/account/signup/process.rs
+3 -3
@@ -1,4 +1,5 @@
1 use super::SignupMethod;
2 +use crate::token::smb_token_file_path;
3 use crate::{
4 account::lib::authorize_github,
5 cli::CommandResult,
@@ -7,12 +8,11 @@ use crate::{
8 use anyhow::{anyhow, Result};
9 use dialoguer::{console::Term, theme::ColorfulTheme, Input, Password, Select};
10 use log::debug;
11 +use network::environment::Environment;
12 use reqwest::{Client, StatusCode};
13 use serde::Serialize;
14 use smbcloud_model::signup::{SignupEmailParams, SignupResult, SignupUserEmail};
13 -use smbcloud_networking::{
14 - constants::PATH_USERS, environment::Environment, smb_base_url_builder, smb_token_file_path,
15 -};
15 +use smbcloud_networking::{constants::PATH_USERS, smb_base_url_builder};
16 use smbcloud_utils::email_validation;
17 use spinners::Spinner;
18
crates/cli/src/cli/mod.rs
+1 -1
@@ -1,6 +1,6 @@
1 use crate::{account, project};
2 use clap::{Parser, Subcommand};
3 -use smbcloud_networking::environment::Environment;
3 +use network::environment::Environment;
4 use spinners::Spinner;
5
6 pub struct CommandResult {
crates/cli/src/deploy/config.rs
+1 -1
@@ -3,13 +3,13 @@ use crate::{
3 ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
4 };
5 use git2::{Cred, CredentialType, Error};
6 +use network::environment::Environment;
7 use serde::{Deserialize, Serialize};
8 use smbcloud_model::{
9 account::User,
10 error_codes::{ErrorCode, ErrorResponse},
11 project::Project,
12 };
12 -use smbcloud_networking::environment::Environment;
13 use smbcloud_networking_project::crud_project_read::get_project;
14 use spinners::Spinner;
15 use std::{fs, path::Path};
crates/cli/src/deploy/mod.rs
+2 -1
@@ -3,6 +3,7 @@ mod git;
3 mod remote_messages;
4 mod setup;
5
6 +use crate::token::get_smb_token;
7 use crate::{
8 account::{lib::is_logged_in, login::process_login, me::me},
9 cli::CommandResult,
@@ -14,9 +15,9 @@ use anyhow::{anyhow, Result};
15 use config::check_config;
16 use git::remote_deployment_setup;
17 use git2::{PushOptions, RemoteCallbacks, Repository};
18 +use network::environment::Environment;
19 use remote_messages::{build_next_app, start_server};
20 use smbcloud_model::project::{DeploymentPayload, DeploymentStatus};
19 -use smbcloud_networking::{environment::Environment, get_smb_token};
21 use smbcloud_networking_project::{
22 crud_project_deployment_create::create_deployment, crud_project_deployment_update::update,
23 };
crates/cli/src/deploy/setup.rs
+2 -1
@@ -1,11 +1,12 @@
1 +use crate::token::get_smb_token;
2 use crate::{deploy::config::Config, ui::highlight};
3 use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
4 +use network::environment::Environment;
5 use regex::Regex;
6 use smbcloud_model::{
7 error_codes::{ErrorCode, ErrorResponse},
8 project::{Project, ProjectCreate},
9 };
8 -use smbcloud_networking::{environment::Environment, get_smb_token};
10 use smbcloud_networking_project::{
11 crud_project_create::create_project, crud_project_read::get_projects,
12 };
crates/cli/src/lib.rs
+1
@@ -2,4 +2,5 @@ pub mod account;
2 pub mod cli;
3 pub mod deploy;
4 pub mod project;
5 +mod token;
6 mod ui;
crates/cli/src/main.rs
+1 -1
@@ -1,6 +1,7 @@
1 use anyhow::{anyhow, Result};
2 use clap::Parser;
3 use console::style;
4 +use network::environment::Environment;
5 use network::network::check_internet_connection;
6 use smbcloud_cli::account::login::process_login;
7 use smbcloud_cli::account::logout::process_logout;
@@ -13,7 +14,6 @@ use smbcloud_cli::{
14 cli::{Cli, Commands},
15 deploy::process_deploy,
16 };
16 -use smbcloud_networking::environment::Environment;
17 use std::{
18 fs::{create_dir_all, OpenOptions},
19 path::PathBuf,
crates/cli/src/project/crud_create.rs
+3 -2
@@ -1,3 +1,4 @@
1 +use crate::token::get_smb_token;
2 use crate::{
3 account::{lib::is_logged_in, login::process_login},
4 cli::CommandResult,
@@ -7,8 +8,8 @@ use anyhow::{anyhow, Result};
8 use chrono::Utc;
9 use console::style;
10 use dialoguer::{theme::ColorfulTheme, Input};
11 +use network::environment::Environment;
12 use smbcloud_model::project::ProjectCreate;
11 -use smbcloud_networking::{environment::Environment, get_smb_token};
13 use smbcloud_networking_project::crud_project_create::create_project;
14 use spinners::Spinner;
15
@@ -94,7 +95,7 @@ name = "{repository_name}"
95 repository = "{repository_name}"
96 description = "{description}"
97 created_at = "{now}"
97 -updated_at = "{now}"
98 +updated_at = "{now}"
99 "#,
100 ),
101 )?;
crates/cli/src/project/crud_delete.rs
+2 -1
@@ -1,3 +1,4 @@
1 +use crate::token::get_smb_token;
2 use crate::{
3 account::lib::is_logged_in,
4 cli::CommandResult,
@@ -5,7 +6,7 @@ use crate::{
6 };
7 use anyhow::{anyhow, Result};
8 use dialoguer::{theme::ColorfulTheme, Input};
8 -use smbcloud_networking::{environment::Environment, get_smb_token};
9 +use network::environment::Environment;
10 use smbcloud_networking_project::crud_project_delete::delete_project;
11 use spinners::Spinner;
12
crates/cli/src/project/crud_read.rs
+2 -1
@@ -1,13 +1,14 @@
1 use std::{fs::OpenOptions, io::Write};
2
3 +use crate::token::get_smb_token;
4 use crate::{
5 cli::CommandResult,
6 ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
7 };
8 use anyhow::{anyhow, Result};
9 use log::debug;
10 +use network::environment::Environment;
11 use smbcloud_model::project::{Config, Project};
10 -use smbcloud_networking::{environment::Environment, get_smb_token};
12 use smbcloud_networking_project::crud_project_read::{get_project, get_projects};
13 use spinners::Spinner;
14 use tabled::{Table, Tabled};
crates/cli/src/project/crud_update.rs
+2 -1
@@ -1,6 +1,7 @@
1 +use crate::token::get_smb_token;
2 use anyhow::{anyhow, Result};
3 use dialoguer::{theme::ColorfulTheme, Input};
3 -use smbcloud_networking::{environment::Environment, get_smb_token};
4 +use network::environment::Environment;
5 use smbcloud_networking_project::{
6 crud_project_read::get_project, crud_project_update::update_project_description,
7 };
crates/cli/src/project/deployment.rs
+2 -1
@@ -1,11 +1,12 @@
1 +use crate::token::get_smb_token;
2 use crate::{
3 cli::CommandResult,
4 deploy::config::{check_config, check_project},
5 ui::{succeed_message, succeed_symbol},
6 };
7 use anyhow::Result;
8 +use network::environment::Environment;
9 use smbcloud_model::project::Deployment;
8 -use smbcloud_networking::{environment::Environment, get_smb_token};
10 use smbcloud_networking_project::crud_project_deployment_read::{get_deployment, get_deployments};
11 use spinners::Spinner;
12 use tabled::{Table, Tabled};
crates/cli/src/project/process.rs
+1 -1
@@ -10,7 +10,7 @@ use crate::{
10 },
11 };
12 use anyhow::Result;
13 -use smbcloud_networking::environment::Environment;
13 +use network::environment::Environment;
14
15 pub async fn process_project(env: Environment, commands: Commands) -> Result<CommandResult> {
16 match commands {
crates/cli/src/token/mod.rs new
+33
@@ -0,0 +1,33 @@
1 +use anyhow::{anyhow, Result};
2 +use dirs::home_dir;
3 +use log::debug;
4 +use network::environment::Environment;
5 +use std::path::{Path, PathBuf};
6 +
7 +pub async fn get_smb_token(env: Environment) -> Result<String> {
8 + if let Some(path) = smb_token_file_path(env) {
9 + std::fs::read_to_string(path).map_err(|e| {
10 + debug!("Error while reading token: {}", &e);
11 + anyhow!("Error while reading token. Are you logged in?")
12 + })
13 + } else {
14 + Err(anyhow!("Failed to get home directory. Are you logged in?"))
15 + }
16 +}
17 +
18 +pub fn smb_token_file_path(env: Environment) -> Option<PathBuf> {
19 + match home_dir() {
20 + Some(home_path) => {
21 + let token_path = [&env.smb_dir(), "/token"].join("");
22 + let token_file = home_path.join(Path::new(&token_path));
23 + if token_file.exists() && token_file.is_file() {
24 + return Some(token_file);
25 + }
26 + None
27 + }
28 + None => {
29 + debug!("Failed to get home directory.");
30 + None
31 + }
32 + }
33 +}
crates/network/Cargo.toml
+1
@@ -8,6 +8,7 @@ crate-type = ["cdylib", "rlib"]
8
9 [dependencies]
10 log = { workspace = true }
11 +clap = { workspace = true, features = ["derive", "env"] }
12 reqwest = { workspace = true, features = ["json"] }
13 serde = { workspace = true, features = ["derive"] }
14 serde_json = { workspace = true }
crates/network/src/environment.rs renamed
crates/network/src/lib.rs
+1
@@ -1 +1,2 @@
1 +pub mod environment;
2 pub mod network;
crates/smbcloud-networking-project/Cargo.toml
-1
@@ -24,7 +24,6 @@ crate-type = ["cdylib", "rlib"]
24 anyhow = { workspace = true }
25 async-trait = { workspace = true, optional = true }
26 dirs = { workspace = true }
27 -home = { workspace = true }
27 log = { workspace = true }
28 network = { workspace = true }
29 maybe-async = { workspace = true, features = ["is_sync"] }
crates/smbcloud-networking-project/src/crud_project_create.rs
+2 -1
@@ -1,11 +1,12 @@
1 use anyhow::Result;
2 +use network::environment::Environment;
3 use network::network::request;
4 use reqwest::Client;
5 use smbcloud_model::{
6 error_codes::ErrorResponse,
7 project::{Project, ProjectCreate},
8 };
8 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
9 +use smbcloud_networking::constants::SMB_USER_AGENT;
10
11 use crate::url_builder::build_project_url;
12
crates/smbcloud-networking-project/src/crud_project_delete.rs
+2 -1
@@ -1,8 +1,9 @@
1 use crate::url_builder::build_project_url_with_id;
2 +use network::environment::Environment;
3 use network::network::request;
4 use reqwest::Client;
5 use smbcloud_model::error_codes::ErrorResponse;
5 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6 +use smbcloud_networking::constants::SMB_USER_AGENT;
7
8 pub async fn delete_project(
9 env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_create.rs
+2 -1
@@ -1,12 +1,13 @@
1 use crate::url_builder::build_project_deployment_index;
2 use anyhow::Result;
3 +use network::environment::Environment;
4 use network::network::request;
5 use reqwest::Client;
6 use smbcloud_model::{
7 error_codes::ErrorResponse,
8 project::{Deployment, DeploymentPayload},
9 };
9 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
10 +use smbcloud_networking::constants::SMB_USER_AGENT;
11
12 pub async fn create_deployment(
13 env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_read.rs
+2 -1
@@ -1,9 +1,10 @@
1 use crate::url_builder::{build_project_deployment, build_project_deployment_index};
2 use anyhow::Result;
3 +use network::environment::Environment;
4 use network::network::request;
5 use reqwest::Client;
6 use smbcloud_model::{error_codes::ErrorResponse, project::Deployment};
6 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
7 +use smbcloud_networking::constants::SMB_USER_AGENT;
8
9 pub async fn get_deployments(
10 env: Environment,
crates/smbcloud-networking-project/src/crud_project_deployment_update.rs
+2 -1
@@ -1,11 +1,12 @@
1 use anyhow::Result;
2 +use network::environment::Environment;
3 use network::network::request;
4 use reqwest::Client;
5 use smbcloud_model::{
6 error_codes::ErrorResponse,
7 project::{Deployment, DeploymentPayload},
8 };
8 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
9 +use smbcloud_networking::constants::SMB_USER_AGENT;
10
11 use crate::url_builder::build_project_deployment;
12
crates/smbcloud-networking-project/src/crud_project_read.rs
+2 -1
@@ -1,8 +1,9 @@
1 use crate::url_builder::{build_project_url, build_project_url_with_id};
2 +use network::environment::Environment;
3 use network::network::request;
4 use reqwest::Client;
5 use smbcloud_model::{error_codes::ErrorResponse, project::Project};
5 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6 +use smbcloud_networking::constants::SMB_USER_AGENT;
7
8 pub async fn get_project(
9 env: Environment,
crates/smbcloud-networking-project/src/crud_project_update.rs
+2 -1
@@ -1,8 +1,9 @@
1 use crate::url_builder::build_project_url_with_id;
2 +use network::environment::Environment;
3 use network::network::request;
4 use reqwest::Client;
5 use smbcloud_model::{error_codes::ErrorResponse, project::Project};
5 -use smbcloud_networking::{constants::SMB_USER_AGENT, environment::Environment};
6 +use smbcloud_networking::constants::SMB_USER_AGENT;
7
8 pub async fn update_project_description(
9 env: Environment,
crates/smbcloud-networking-project/src/url_builder.rs
+2 -1
@@ -1,4 +1,5 @@
1 -use smbcloud_networking::{environment::Environment, smb_base_url_builder};
1 +use network::environment::Environment;
2 +use smbcloud_networking::smb_base_url_builder;
3
4 // Private functions
5
crates/smbcloud-networking/Cargo.toml
+1 -12
@@ -21,16 +21,5 @@ categories = [
21 crate-type = ["cdylib", "rlib"]
22
23 [dependencies]
24 -anyhow = { workspace = true }
25 -async-trait = { workspace = true, optional = true }
26 -clap = { workspace = true, features = ["derive", "env"] }
27 -dirs = { workspace = true }
28 -home = { workspace = true }
29 -log = { workspace = true }
30 -maybe-async = { workspace = true, features = ["is_sync"] }
31 -reqwest = { workspace = true, features = ["json"] }
32 -serde = { workspace = true, features = ["derive"] }
33 -serde_json = { workspace = true }
34 -smbcloud-model = { workspace = true }
35 -thiserror = { workspace = true }
24 +network = { workspace = true }
25 url-builder = { workspace = true }
crates/smbcloud-networking/src/lib.rs
+1 -33
@@ -1,41 +1,9 @@
1 pub mod constants;
2 -pub mod environment;
2
4 -use anyhow::{anyhow, Result};
3 use constants::{SMB_CLIENT_ID, SMB_CLIENT_SECRET};
6 -use environment::Environment;
7 -use log::debug;
8 -use std::path::{Path, PathBuf};
4 +use network::environment::Environment;
5 use url_builder::URLBuilder;
6
11 -pub async fn get_smb_token(env: Environment) -> Result<String> {
12 - if let Some(path) = smb_token_file_path(env) {
13 - std::fs::read_to_string(path).map_err(|e| {
14 - debug!("Error while reading token: {}", &e);
15 - anyhow!("Error while reading token. Are you logged in?")
16 - })
17 - } else {
18 - Err(anyhow!("Failed to get home directory. Are you logged in?"))
19 - }
20 -}
21 -
22 -pub fn smb_token_file_path(env: Environment) -> Option<PathBuf> {
23 - match home::home_dir() {
24 - Some(home_path) => {
25 - let token_path = [&env.smb_dir(), "/token"].join("");
26 - let token_file = home_path.join(Path::new(&token_path));
27 - if token_file.exists() && token_file.is_file() {
28 - return Some(token_file);
29 - }
30 - None
31 - }
32 - None => {
33 - debug!("Failed to get home directory.");
34 - None
35 - }
36 - }
37 -}
38 -
7 pub fn smb_base_url_builder(env: Environment) -> URLBuilder {
8 let mut url_builder = URLBuilder::new();
9 url_builder