Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Rename project new/rm to start/stop, add restart + other args fixes #771

Merged
merged 5 commits into from
Apr 4, 2023
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
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,9 @@ deploy-examples: deploy-examples/rocket/hello-world \
echo "All example have been redeployed"

deploy-examples/%:
cd examples/$(*); $(shuttle-command) project rm || echo -e "\x1B[33m>> Nothing to remove for $*\x1B[39m"
cd examples/$(*); $(shuttle-command) project stop || echo -e "\x1B[33m>> Nothing to remove for $*\x1B[39m"
sleep 5
cd examples/$(*); $(shuttle-command) project new
cd examples/$(*); $(shuttle-command) project start
sleep 5
cd examples/$(*); $(shuttle-command) deploy

Expand Down
84 changes: 45 additions & 39 deletions cargo-shuttle/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ use crate::init::Framework;
about,
// Cargo passes in the subcommand name to the invoked executable. Use a
// hidden, optional positional argument to deal with it.
arg(clap::Arg::new("dummy")
arg(clap::Arg::new("dummy")
.value_parser([PossibleValue::new("shuttle")])
.required(false)
.hide(true))
)]
pub struct Args {
/// run this command against the api at the supplied url
/// Run this command against the API at the supplied URL
/// (allows targeting a custom deployed instance for this command only)
#[arg(long, env = "SHUTTLE_API")]
pub api_url: Option<String>,
Expand Down Expand Up @@ -85,28 +85,28 @@ impl ProjectArgs {

#[derive(Parser)]
pub enum Command {
/// deploy a shuttle service
/// Deploy a shuttle service
Deploy(DeployArgs),
/// manage deployments of a shuttle service
/// Manage deployments of a shuttle service
#[command(subcommand)]
Deployment(DeploymentCommand),
/// manage resources of a shuttle project
/// Manage resources of a shuttle project
#[command(subcommand)]
Resource(ResourceCommand),
/// create a new shuttle service
/// Create a new shuttle project
Init(InitArgs),
/// generate shell completions
/// Generate shell completions
Generate {
/// which shell
/// Which shell
#[arg(short, long, env, default_value_t = Shell::Bash)]
shell: Shell,
/// output to file or stdout by default
/// Output to a file (stdout by default)
#[arg(short, long, env)]
output: Option<PathBuf>,
},
/// view the status of a shuttle service
/// View the status of a shuttle service
Status,
/// view the logs of a deployment in this shuttle service
/// View the logs of a deployment in this shuttle service
Logs {
/// Deployment ID to get logs for. Defaults to currently running deployment
id: Option<Uuid>,
Expand All @@ -115,30 +115,30 @@ pub enum Command {
/// Follow log output
follow: bool,
},
/// remove artifacts that were generated by cargo
/// Remove cargo build artifacts in the shuttle environment
Clean,
/// stop this shuttle service
/// Stop this shuttle service
Stop,
/// manage secrets for this shuttle service
/// Manage secrets for this shuttle service
Secrets,
/// login to the shuttle platform
/// Login to the shuttle platform
Login(LoginArgs),
/// log out of the shuttle platform
/// Log out of the shuttle platform
Logout,
/// run a shuttle service locally
/// Run a shuttle service locally
Run(RunArgs),
/// Open an issue on github and provide feedback.
/// Open an issue on GitHub and provide feedback
Feedback,
/// manage a project on shuttle
/// List or manage projects on shuttle
#[command(subcommand)]
Project(ProjectCommand),
}

#[derive(Parser)]
pub enum DeploymentCommand {
/// list all the deployments for a service
/// List all the deployments for a service
List,
/// view status of a deployment
/// View status of a deployment
Status {
/// ID of deployment to get status for
id: Uuid,
Expand All @@ -147,57 +147,63 @@ pub enum DeploymentCommand {

#[derive(Parser)]
pub enum ResourceCommand {
/// list all the resources for a project
/// List all the resources for a project
List,
}

#[derive(Parser)]
pub enum ProjectCommand {
/// create an environment for this project on shuttle
New {
/// Create an environment for this project on shuttle
Start {
#[arg(long, default_value_t = IDLE_MINUTES)]
/// How long to wait before putting the project in an idle state due to inactivity. 0 means the project will never idle
idle_minutes: u64,
},
/// list all projects belonging to the calling account
List {
#[arg(long)]
/// Return projects filtered by a given project status
filter: Option<String>,
},
/// remove this project environment from shuttle
Rm,
/// show the status of this project's environment on shuttle
/// Check the status of this project's environment on shuttle
Status {
#[arg(short, long)]
/// Follow status of project command
follow: bool,
},
/// Destroy this project's environment (container) on shuttle
Stop,
/// Destroy and create an environment for this project on shuttle
Restart {
#[arg(long, default_value_t = IDLE_MINUTES)]
/// How long to wait before putting the project in an idle state due to inactivity. 0 means the project will never idle
idle_minutes: u64,
},
/// List all projects belonging to the calling account
List {
#[arg(long)]
/// Return projects filtered by a given project status
filter: Option<String>,
},
}

#[derive(Parser, Clone, Debug)]
pub struct LoginArgs {
/// api key for the shuttle platform
/// API key for the shuttle platform
#[arg(long)]
pub api_key: Option<String>,
}

#[derive(Parser)]
pub struct DeployArgs {
/// allow dirty working directories to be packaged
/// Allow deployment with uncommited files
#[arg(long)]
pub allow_dirty: bool,
/// allows pre-deploy tests to be skipped
/// Don't run pre-deploy tests
#[arg(long)]
pub no_test: bool,
}

#[derive(Parser, Debug)]
pub struct RunArgs {
/// port to start service on
/// Port to start service on
#[arg(long, env, default_value = "8000")]
pub port: u16,
/// use 0.0.0.0 instead of localhost (for usage with local external devices)
/// Use 0.0.0.0 instead of localhost (for usage with local external devices)
#[arg(long)]
pub external: bool,
/// Use release mode for building the project.
Expand Down Expand Up @@ -243,7 +249,7 @@ pub struct InitArgs {
/// Initialize without a framework
#[arg(long, conflicts_with_all = &["actix_web","axum", "rocket", "tide", "tower", "poem", "warp", "salvo", "serenity", "poise", "thruster"])]
pub no_framework: bool,
/// Whether to create the environment for this project on Shuttle
/// Whether to create the environment for this project on shuttle
#[arg(long)]
pub new: bool,
#[command(flatten)]
Expand Down
73 changes: 42 additions & 31 deletions cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::path::{Path, PathBuf};
use std::process::exit;
use std::str::FromStr;

use anyhow::{anyhow, bail, Context, Result};
use anyhow::{bail, Context, Result};
pub use args::{Args, Command, DeployArgs, InitArgs, LoginArgs, ProjectArgs, RunArgs};
use cargo_metadata::Message;
use clap::CommandFactory;
Expand Down Expand Up @@ -69,7 +69,13 @@ impl Shuttle {
Command::Deploy(..)
| Command::Deployment(..)
| Command::Resource(..)
| Command::Project(..)
| Command::Project(
// ProjectCommand::List does not need to know which project we are in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one 😍

ProjectCommand::Start { .. }
| ProjectCommand::Stop { .. }
| ProjectCommand::Restart { .. }
| ProjectCommand::Status { .. }
)
| Command::Stop
| Command::Clean
| Command::Secrets
Expand Down Expand Up @@ -104,16 +110,19 @@ impl Shuttle {
Command::Stop => self.stop(&self.client()?).await,
Command::Clean => self.clean(&self.client()?).await,
Command::Secrets => self.secrets(&self.client()?).await,
Command::Project(ProjectCommand::New { idle_minutes }) => {
Command::Project(ProjectCommand::Start { idle_minutes }) => {
self.project_create(&self.client()?, idle_minutes).await
}
Command::Project(ProjectCommand::Restart { idle_minutes }) => {
self.project_recreate(&self.client()?, idle_minutes).await
}
Command::Project(ProjectCommand::Status { follow }) => {
self.project_status(&self.client()?, follow).await
}
Command::Project(ProjectCommand::List { filter }) => {
self.projects_list(&self.client()?, filter).await
}
Command::Project(ProjectCommand::Rm) => self.project_delete(&self.client()?).await,
Command::Project(ProjectCommand::Stop) => self.project_delete(&self.client()?).await,
}
.map(|_| CommandOutcome::Ok)
}
Expand Down Expand Up @@ -344,7 +353,7 @@ impl Shuttle {
if let Some(deployment) = summary.deployment {
deployment.id
} else {
return Err(anyhow!("could not automatically find a running deployment for '{}'. Try passing a deployment ID manually", self.ctx.project_name()));
bail!("Could not automatically find a running deployment for '{}'. Try passing a deployment ID manually", self.ctx.project_name());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't quite remember, but doesn't return Err(...) make the format of the error better by catching the Err somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From https://docs.rs/anyhow/latest/anyhow/macro.bail.html

This macro is equivalent to return Err(anyhow!($args...)).

I'd be surprised if that actually affected formatting 🧐

}
};

Expand Down Expand Up @@ -728,6 +737,13 @@ impl Shuttle {
Ok(())
}

async fn project_recreate(&self, client: &Client, idle_minutes: u64) -> Result<()> {
self.project_delete(client).await?;
self.project_create(client, idle_minutes).await?;

Ok(())
}

async fn projects_list(&self, client: &Client, filter: Option<String>) -> Result<()> {
let projects = match filter {
Some(filter) => {
Expand All @@ -736,7 +752,7 @@ impl Shuttle {
.get_projects_list_filtered(filter.to_string())
.await?
} else {
return Err(anyhow!("That's not a valid project status!"));
bail!("That's not a valid project status!");
}
}
None => client.get_projects_list().await?,
Expand All @@ -750,26 +766,23 @@ impl Shuttle {
}

async fn project_status(&self, client: &Client, follow: bool) -> Result<()> {
match follow {
true => {
self.wait_with_spinner(
&[
project::State::Ready,
project::State::Destroyed,
project::State::Errored {
message: Default::default(),
},
],
client.get_project(self.ctx.project_name()),
self.ctx.project_name(),
client,
)
.await?;
}
false => {
let project = client.get_project(self.ctx.project_name()).await?;
println!("{project}");
}
if follow {
self.wait_with_spinner(
&[
project::State::Ready,
project::State::Destroyed,
project::State::Errored {
message: Default::default(),
},
],
client.get_project(self.ctx.project_name()),
self.ctx.project_name(),
client,
)
.await?;
} else {
let project = client.get_project(self.ctx.project_name()).await?;
println!("{project}");
}

Ok(())
Expand Down Expand Up @@ -917,9 +930,9 @@ impl Shuttle {
}

writeln!(error).expect("to append error");
writeln!(error, "to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag").expect("to append error");
writeln!(error, "To proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag").expect("to append error");

return Err(anyhow::Error::msg(error));
bail!(error);
}
}

Expand Down Expand Up @@ -955,9 +968,7 @@ fn check_version(runtime_path: &Path) -> Result<()> {
if runtime_version == valid_version {
Ok(())
} else {
Err(anyhow!(
"shuttle-runtime and cargo-shuttle are not the same version"
))
bail!("shuttle-runtime and cargo-shuttle are not the same version")
}
}

Expand Down