5 files changed
+36
-25
crates/cli/src/account/lib.rs
+2
-9
@@ -20,8 +20,6 @@ use std::{
20
};
21
use url_builder::URLBuilder;
22
23
-use crate::ui::fail_message;
24
-
23
pub async fn authorize_github(env: &Environment) -> Result<SmbAuthorization> {
24
// Spin up a simple localhost server to listen for the GitHub OAuth callback
25
// setup_oauth_callback_server();
@@ -242,12 +240,7 @@ pub async fn save_token(env: Environment, response: &Response) -> Result<()> {
240
}
241
}
242
245
-pub async fn protected_request(env: Environment) -> Result<()> {
243
+pub fn is_logged_in(env: Environment) -> bool {
244
// Check if token file exists
247
- if smb_token_file_path(env).is_none() {
248
- return Err(anyhow!(fail_message(
249
- "Please authorize your account first with `smb account login` command."
250
- )));
251
- }
252
- Ok(())
245
+ smb_token_file_path(env).is_some()
246
}
crates/cli/src/deploy/config.rs
+2
-2
@@ -1,5 +1,5 @@
1
use crate::{
2
- deploy::setup::setup,
2
+ deploy::setup::setup_project,
3
ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
4
};
5
use git2::{Cred, CredentialType, Error};
@@ -23,7 +23,7 @@ pub(crate) async fn check_config(env: Environment) -> Result<Config, ConfigError
23
let config_path = Path::new(".smb/config.toml");
24
if !config_path.exists() {
25
spinner.stop_and_persist(&succeed_symbol(), succeed_message("Setting up deployment"));
26
- setup(env).await?;
26
+ setup_project(env).await?;
27
}
28
29
// Parse toml file
crates/cli/src/deploy/mod.rs
+4
-2
@@ -4,7 +4,7 @@ mod remote_messages;
4
mod setup;
5
6
use crate::{
7
- account::lib::protected_request,
7
+ account::{lib::is_logged_in, login::process_login},
8
cli::CommandResult,
9
deploy::config::check_project,
10
ui::{fail_message, succeed_message, succeed_symbol},
@@ -22,7 +22,9 @@ use spinners::Spinner;
22
23
pub async fn process_deploy(env: Environment) -> Result<CommandResult> {
24
// Check credentials.
25
- protected_request(env).await?;
25
+ if !is_logged_in(env) {
26
+ let _ = process_login(env).await;
27
+ }
28
29
// Check config.
30
let config = check_config(env).await?;
crates/cli/src/deploy/setup.rs
+23
-9
@@ -1,11 +1,12 @@
1
use crate::{deploy::config::{Config, ConfigError}, ui::highlight};
2
use dialoguer::{theme::ColorfulTheme, Confirm, Input, Select};
3
+use regex::Regex;
4
use smbcloud_model::project::{Project, ProjectCreate};
5
use smbcloud_networking::environment::Environment;
6
use smbcloud_networking_project::{create_project, get_all};
7
use std::{env, fs, path::Path};
8
8
-pub async fn setup(env: Environment) -> Result<Config, ConfigError> {
9
+pub async fn setup_project(env: Environment) -> Result<Config, ConfigError> {
10
let path = env::current_dir().ok();
11
let path_str = path
12
.as_ref()
@@ -26,10 +27,10 @@ pub async fn setup(env: Environment) -> Result<Config, ConfigError> {
27
Err(_) => return Err(ConfigError::InputError),
28
};
29
29
- let project = if !projects.is_empty() {
30
- select_project(env, projects).await?
30
+ let project: Project = if !projects.is_empty() {
31
+ select_project(env, projects, &path_str).await?
32
} else {
32
- create_new_project(env).await?
33
+ create_new_project(env, &path_str).await?
34
};
35
36
let name = project.name.clone();
@@ -57,14 +58,14 @@ pub async fn setup(env: Environment) -> Result<Config, ConfigError> {
58
Ok(config)
59
}
60
60
-async fn select_project(env: Environment, projects: Vec<Project>) -> Result<Project, ConfigError> {
61
+async fn select_project(env: Environment, projects: Vec<Project>, path: &str) -> Result<Project, ConfigError> {
62
let confirm = Confirm::with_theme(&ColorfulTheme::default())
63
.with_prompt("Use existing project? y/n")
64
.interact()
65
.map_err(|_| ConfigError::InputError)?;
66
67
if !confirm {
67
- return create_new_project(env).await;
68
+ return create_new_project(env, path).await;
69
}
70
let selection = Select::with_theme(&ColorfulTheme::default())
71
.items(&projects)
@@ -77,9 +78,15 @@ async fn select_project(env: Environment, projects: Vec<Project>) -> Result<Proj
78
Ok(project)
79
}
80
80
-async fn create_new_project(env: Environment) -> Result<Project, ConfigError> {
81
+async fn create_new_project(env: Environment, path: &str) -> Result<Project, ConfigError> {
82
+ let default_name = Path::new(path)
83
+ .file_name()
84
+ .and_then(|os_str| os_str.to_str())
85
+ .unwrap_or("project");
86
+
87
let name = match Input::<String>::with_theme(&ColorfulTheme::default())
88
.with_prompt("Project name")
89
+ .default(default_name.to_string())
90
.interact()
91
{
92
Ok(project_name) => project_name,
@@ -87,16 +94,23 @@ async fn create_new_project(env: Environment) -> Result<Project, ConfigError> {
94
return Err(ConfigError::InputError);
95
}
96
};
97
+
98
+ // Create a repository name: lowercased, remove spaces and special characters
99
+ let re = Regex::new(r"[^a-zA-Z0-9_-]").unwrap();
100
+ let default_repository = name.clone().to_lowercase().replace(' ', "_");
101
+ let default_repo = re.replace_all(&default_repository, "");
102
+
103
let repository = match Input::<String>::with_theme(&ColorfulTheme::default())
91
- .default(name.clone())
104
+ .default(default_repo.to_string())
105
.with_prompt("Repository")
106
.interact()
107
{
95
- Ok(project_name) => project_name,
108
+ Ok(repo) => repo,
109
Err(_) => {
110
return Err(ConfigError::InputError);
111
}
112
};
113
+
114
let description = match Input::<String>::with_theme(&ColorfulTheme::default())
115
.with_prompt("Description")
116
.interact()
crates/cli/src/project/crud_create.rs
+5
-3
@@ -1,18 +1,20 @@
1
use crate::{
2
- account::lib::protected_request,
2
+ account::{lib::is_logged_in, login::process_login},
3
cli::CommandResult,
4
ui::{fail_message, succeed_message, succeed_symbol},
5
};
6
use anyhow::{anyhow, Result};
7
use console::style;
8
use dialoguer::{theme::ColorfulTheme, Input};
9
-use smbcloud_model::project::{self, ProjectCreate};
9
+use smbcloud_model::project::ProjectCreate;
10
use smbcloud_networking::environment::Environment;
11
use smbcloud_networking_project::create_project;
12
use spinners::Spinner;
13
14
pub async fn process_project_init(env: Environment) -> Result<CommandResult> {
15
- protected_request(env).await?;
15
+ if !is_logged_in(env) {
16
+ let _ = process_login(env).await;
17
+ }
18
19
let project_name = match Input::<String>::with_theme(&ColorfulTheme::default())
20
.with_prompt("Project name")