Skip to content

Commit

Permalink
feat: 'clean' subcommand (#530)
Browse files Browse the repository at this point in the history
* feat: 'clean' subcommand

* refactor: output cleaning is done
  • Loading branch information
chesedo authored Dec 14, 2022
1 parent 18767f0 commit 8e93e87
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 3 deletions.
2 changes: 2 additions & 0 deletions cargo-shuttle/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub enum Command {
/// Follow log output
follow: bool,
},
/// remove artifacts that were generated by cargo
Clean,
/// delete this shuttle service
Delete,
/// manage secrets for this shuttle service
Expand Down
10 changes: 10 additions & 0 deletions cargo-shuttle/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,16 @@ impl Client {
.await
}

pub async fn clean_project(&self, project: &ProjectName) -> Result<Vec<String>> {
let path = format!("/projects/{}/clean", project.as_str(),);

self.post(path, Option::<String>::None)
.await
.context("failed to get clean output")?
.to_json()
.await
}

pub async fn get_project(&self, project: &ProjectName) -> Result<project::Response> {
let path = format!("/projects/{}", project.as_str());

Expand Down
14 changes: 14 additions & 0 deletions cargo-shuttle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ impl Shuttle {
| Command::Deployment(..)
| Command::Project(..)
| Command::Delete
| Command::Clean
| Command::Secrets
| Command::Status
| Command::Logs { .. }
Expand Down Expand Up @@ -91,6 +92,7 @@ impl Shuttle {
self.deployment_get(&client, id).await
}
Command::Delete => self.delete(&client).await,
Command::Clean => self.clean(&client).await,
Command::Secrets => self.secrets(&client).await,
Command::Auth(auth_args) => self.auth(auth_args, &client).await,
Command::Project(ProjectCommand::New) => self.project_create(&client).await,
Expand Down Expand Up @@ -299,6 +301,18 @@ impl Shuttle {
Ok(())
}

async fn clean(&self, client: &Client) -> Result<()> {
let lines = client.clean_project(self.ctx.project_name()).await?;

for line in lines {
println!("{line}");
}

println!("Cleaning done!");

Ok(())
}

async fn logs(&self, client: &Client, id: Option<Uuid>, follow: bool) -> Result<()> {
let id = if let Some(id) = id {
id
Expand Down
9 changes: 8 additions & 1 deletion deployer/src/deployment/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const KILL_BUFFER_SIZE: usize = 10;
pub struct DeploymentManager {
pipeline: Pipeline,
kill_send: KillSender,
storage_manager: StorageManager,
}

impl DeploymentManager {
Expand All @@ -40,6 +41,7 @@ impl DeploymentManager {
artifacts_path: PathBuf,
) -> Self {
let (kill_send, _) = broadcast::channel(KILL_BUFFER_SIZE);
let storage_manager = StorageManager::new(artifacts_path);

DeploymentManager {
pipeline: Pipeline::new(
Expand All @@ -49,9 +51,10 @@ impl DeploymentManager {
build_log_recorder,
secret_recorder,
active_deployment_getter,
StorageManager::new(artifacts_path),
storage_manager.clone(),
),
kill_send,
storage_manager,
}
}

Expand All @@ -76,6 +79,10 @@ impl DeploymentManager {
self.kill_send.send(id).unwrap();
}
}

pub fn storage_manager(&self) -> StorageManager {
self.storage_manager.clone()
}
}

/// ```no-test
Expand Down
2 changes: 2 additions & 0 deletions deployer/src/handlers/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ pub enum Error {
},
#[error("record could not be found")]
NotFound,
#[error("Custom error: {0}")]
Custom(#[from] anyhow::Error),
}

impl Serialize for Error {
Expand Down
18 changes: 17 additions & 1 deletion deployer/src/handlers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use axum::extract::ws::{self, WebSocket};
use axum::extract::{Extension, MatchedPath, Path, Query};
use axum::http::{Request, Response};
use axum::middleware::from_extractor;
use axum::routing::{get, Router};
use axum::routing::{get, post, Router};
use axum::{extract::BodyStream, Json};
use bytes::BufMut;
use chrono::{TimeZone, Utc};
Expand All @@ -17,6 +17,7 @@ use shuttle_common::backends::metrics::Metrics;
use shuttle_common::models::secret;
use shuttle_common::project::ProjectName;
use shuttle_common::LogItem;
use shuttle_service::loader::clean_crate;
use tower_http::auth::RequireAuthorizationLayer;
use tower_http::trace::TraceLayer;
use tracing::{debug, debug_span, error, field, instrument, trace, Span};
Expand Down Expand Up @@ -66,6 +67,7 @@ pub fn make_router(
"/projects/:project_name/secrets/:service_name",
get(get_secrets),
)
.route("/projects/:project_name/clean", post(post_clean))
.layer(Extension(persistence))
.layer(Extension(deployment_manager))
.layer(Extension(proxy_fqdn))
Expand Down Expand Up @@ -416,6 +418,20 @@ async fn get_secrets(
}
}

async fn post_clean(
Extension(deployment_manager): Extension<DeploymentManager>,
Path(project_name): Path<String>,
) -> Result<Json<Vec<String>>> {
let project_path = deployment_manager
.storage_manager()
.service_build_path(project_name)
.map_err(anyhow::Error::new)?;

let lines = clean_crate(&project_path, true)?;

Ok(Json(lines))
}

async fn get_status() -> String {
"Ok".to_string()
}
47 changes: 46 additions & 1 deletion service/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::path::{Path, PathBuf};
use anyhow::{anyhow, Context};
use cargo::core::compiler::{CompileMode, MessageFormat};
use cargo::core::{Manifest, PackageId, Shell, Summary, Verbosity, Workspace};
use cargo::ops::{compile, CompileOptions};
use cargo::ops::{clean, compile, CleanOptions, CompileOptions};
use cargo::util::interning::InternedString;
use cargo::util::{homedir, ToSemver};
use cargo::Config;
Expand Down Expand Up @@ -147,6 +147,51 @@ pub async fn build_crate(
Ok(compilation?.cdylibs[0].path.clone())
}

pub fn clean_crate(project_path: &Path, release_mode: bool) -> anyhow::Result<Vec<String>> {
let (read, write) = pipe::pipe();
let project_path = project_path.to_owned();

tokio::task::spawn_blocking(move || {
let config = get_config(write).unwrap();
let manifest_path = project_path.join("Cargo.toml");
let ws = Workspace::new(&manifest_path, &config).unwrap();

let requested_profile = if release_mode {
InternedString::new("release")
} else {
InternedString::new("dev")
};

let opts = CleanOptions {
config: &config,
spec: Vec::new(),
targets: Vec::new(),
requested_profile,
profile_specified: true,
doc: false,
};

clean(&ws, &opts).unwrap();
});

let mut lines = Vec::new();

for message in Message::parse_stream(read) {
trace!(?message, "parsed cargo message");
match message {
Ok(Message::TextLine(line)) => {
lines.push(line);
}
Ok(_) => {}
Err(error) => {
error!("failed to parse cargo message: {error}");
}
}
}

Ok(lines)
}

/// Get the default compile config with output redirected to writer
pub fn get_config(writer: PipeWriter) -> anyhow::Result<Config> {
let mut shell = Shell::from_write(Box::new(writer));
Expand Down

0 comments on commit 8e93e87

Please sign in to comment.