Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/commands/get/projects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ pub async fn command(args: Args) -> Result<()> {
.context("Failed to get projects from server".red())?;
let remote_projects = remote_projects
.iter()
.filter(|p| !local_projects.iter().any(|lp| lp.project_id == **p))
.map(|p| format!("{} - {}", p, "Remote".green()));
.filter(|p| !local_projects.iter().any(|lp| lp.project_id == p.project_id))
.map(|p| format!("{} - {} - {}", p.project_id, p.project_name, "Remote".green()));

let local_projects = local_projects
.iter()
.map(|p| format!("{} - {}", p.project_id, p.path.display()));
Expand Down
27 changes: 26 additions & 1 deletion src/commands/new/project.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::*;
use crate::utils::prompt::prompt_text;
use crate::{sdk::SDK, utils::config::get_config};

/// Create a new project
Expand All @@ -7,12 +8,36 @@ pub struct Args {
/// Key
#[clap(short, long)]
key: Option<String>,

/// Project name
#[clap(short, long)]
name: Option<String>,
Comment thread
flatypus marked this conversation as resolved.

#[clap(long)]
nn: bool,
}

pub async fn command(args: Args) -> Result<()> {
let config = get_config()?;
let key = config.get_key_or_default(args.key)?;
let new_project_id = SDK::new_project(&key.fingerprint).await?;

// check if nn flag is set
if args.nn {
let new_project_id = SDK::new_project(&key.fingerprint, "").await?;
println!("Created new project with ID: {}", new_project_id);
return Ok(());
}

let name;
if args.nn {
name = "".to_string();
} else {
name = args.name.unwrap_or_else(|| {
prompt_text("What is the name of this project?").unwrap()
});
}

let new_project_id = SDK::new_project(&key.fingerprint, &name).await?;
println!("Created new project with ID: {}", new_project_id);
Ok(())
}
37 changes: 26 additions & 11 deletions src/sdk.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::*;
use crate::{
types::ProjectInfo,
types::ListProjects,
utils::{
auth::get_token,
config::get_config,
Expand Down Expand Up @@ -81,9 +82,10 @@ impl SDK {
project_id: &str,
partial_fingerprint: &str,
) -> Result<ProjectInfo> {
// GET /v2/project/:id
let client = reqwest::Client::new();

let url = get_api_url().join("project/")?.join(project_id)?;
let url = get_api_url().join("v2/project/")?.join(project_id)?;

let project_info = client
.get(url)
Expand Down Expand Up @@ -431,11 +433,11 @@ impl SDK {

pub async fn list_projects(
partial_fingerprint: &str,
) -> Result<Vec<String>> {
// GET /projects
) -> Result<Vec<ListProjects>> {
// GET /v2/projects
let client = reqwest::Client::new();

let url = get_api_url().join("projects")?;
let url = get_api_url().join("v2/projects")?;

let res = client
.get(url)
Expand All @@ -447,24 +449,37 @@ impl SDK {
.await
.context("Failed to get projects")?;

let res = res
.json::<Vec<String>>()
let projects = res
.json::<Vec<ListProjects>>()
.await
.context("Failed to parse API response into Vec<String>")?;
.context("Failed to parse API response into Vec<ProjectInfo>")?;

Ok(res)
let project_data = projects
.iter()
.map(|p| ListProjects {
project_id: p.project_id.clone(),
project_name: p.project_name.clone(),
})
.collect::<Vec<ListProjects>>();

Ok(project_data)
}

pub async fn new_project(partial_fingerprint: &str) -> Result<String> {
// POST /projects/new
pub async fn new_project(partial_fingerprint: &str, project_name: &str) -> Result<String> {
// POST /v2/projects/new
let client = reqwest::Client::new();

let body = json!({
"name": project_name
});

let res = client
.post(get_api_url().join("projects/new")?)
.post(get_api_url().join("v2/projects/new")?)
.header(
header::AUTHORIZATION,
Self::auth_header(partial_fingerprint).await?,
)
.json(&body)
.send()
.await?
.text()
Expand Down
7 changes: 7 additions & 0 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,16 @@ pub struct PartialUser {
#[derive(Serialize, Deserialize, Debug)]
pub struct ProjectInfo {
pub project_id: String,
pub project_name: String,
pub users: Vec<User>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct ListProjects {
pub project_id: String,
pub project_name: String,
}

impl Display for User {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} - {}", self.username, self.id)
Expand Down
5 changes: 2 additions & 3 deletions src/utils/choice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ impl Choice {
let key = config.get_key(partial_fingerprint)?;
Ok((key, config))
}

pub async fn choose_project(partial_fingerprint: &str) -> Result<String> {
let (key, config) = Self::get_key(partial_fingerprint)?;
let all_projects = SDK::list_projects(&key.fingerprint).await?;
Expand All @@ -23,7 +22,7 @@ impl Choice {

let all_projects = all_projects
.iter()
.filter(|p| !local_projects.iter().any(|lp| &lp.project_id == *p))
.filter(|p| !local_projects.iter().any(|lp| lp.project_id == p.project_id))
.collect::<Vec<_>>();

let mut options = local_projects
Expand All @@ -32,7 +31,7 @@ impl Choice {
.collect::<Vec<_>>();

all_projects.iter().for_each(|p| {
options.push(format!("{} - {}", p, "Remote"));
options.push(format!("{} - {} - {}", p.project_id, p.project_name, "Remote"));
});

let selected =
Expand Down