Skip to content

Commit

Permalink
Anycloud cli linting and lint checking (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Mar 18, 2021
1 parent 85c1738 commit a371d70
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 57 deletions.
28 changes: 28 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the main branch
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:

cli-style:
# The type of runner that the job will run on
runs-on: ubuntu-latest

# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2

# Rust is automatically set up and included by default according to: https://github.com/actions/starter-workflows/blob/master/ci/rust.yml
# Run cargo fmt linting on the source code
- name: Run style linter
run: cd cli && cargo fmt -- --check
8 changes: 5 additions & 3 deletions cli/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ fn main() {
let alan_version = String::from_utf8_lossy(&alan_version_output.stdout);
println!("cargo:rustc-env=ALAN_VERSION={}", &alan_version);
}

// Tell Cargo that if the anycloud.ln file changes, rerun this build script
println!("cargo:rerun-if-changed=alan/anycloud.ln");
let output = Command::new("sh")
Expand All @@ -26,6 +26,8 @@ fn main() {
// The `alan` command doesn't exist on this machine. We'll guarantee that it does for building
// the `anycloud` binary, but for those using this repo as a library, we'll just bypass this
// piece since only `main.rs` uses the `anycloud.agz` file.
Command::new("sh").arg("-c").arg("cd alan && touch anycloud.agz");
Command::new("sh")
.arg("-c")
.arg("cd alan && touch anycloud.agz");
}
}
}
91 changes: 57 additions & 34 deletions cli/src/deploy/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ use spinner::SpinnerBuilder;
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::fmt::Display;
use std::fs::{File, read};
use std::fs::{read, File};
use std::io::BufReader;
use std::path::Path;

use ascii_table::{AsciiTable, Column};
use base64;

const REQUEST_TIMEOUT: &str = "Operation is still in progress. It might take a few more minutes for \
const REQUEST_TIMEOUT: &str =
"Operation is still in progress. It might take a few more minutes for \
the cloud provider to finish up.";
const FORBIDDEN_OPERATION: &str = "Please review your credentials. Make sure you have follow all the \
const FORBIDDEN_OPERATION: &str =
"Please review your credentials. Make sure you have follow all the \
configuration steps: https://alantech.gitbook.io/anycloud/";
const NAME_CONFLICT: &str = "Another application with same App Id already exists.";

Expand Down Expand Up @@ -124,7 +126,10 @@ fn get_deploy_config() -> HashMap<String, Vec<DeployConfig>> {
let path = Path::new(file_name);
let file = File::open(path);
if let Err(err) = file {
println!("Cannot access deploy config at {}. Error: {}", file_name, err);
println!(
"Cannot access deploy config at {}. Error: {}",
file_name, err
);
println!("{}", CONFIG_SETUP);
std::process::exit(1);
}
Expand Down Expand Up @@ -159,13 +164,10 @@ pub fn get_config() -> HashMap<String, Vec<Config>> {
for deploy_config in deploy_configs {
let credentials = cred_configs
.get(&deploy_config.credentials)
.expect(
&format!("Credentials {} for deploy config {} not found in {}",
&deploy_config.credentials,
deploy_id,
CREDENTIALS_CONFIG_FILE
)
);
.expect(&format!(
"Credentials {} for deploy config {} not found in {}",
&deploy_config.credentials, deploy_id, CREDENTIALS_CONFIG_FILE
));
configs.push(Config {
credentials: credentials.credentials.clone(),
cloudProvider: credentials.cloudProvider.to_string(),
Expand All @@ -185,8 +187,8 @@ pub async fn post_v1(endpoint: &str, body: Value) -> Result<String, PostV1Error>
.header("Content-Type", "application/json")
.body(body.to_string().into());
let req = match req {
Ok(req) => req,
Err(e) => return Err(PostV1Error::Other(e.into())),
Ok(req) => req,
Err(e) => return Err(PostV1Error::Other(e.into())),
};
let resp = client.request(req).await;
let mut resp = match resp {
Expand All @@ -209,7 +211,7 @@ pub async fn post_v1(endpoint: &str, body: Value) -> Result<String, PostV1Error>
StatusCode::FORBIDDEN => Err(PostV1Error::Forbidden),
StatusCode::CONFLICT => Err(PostV1Error::Conflict),
_ => Err(PostV1Error::Other(data_str.into())),
}
};
}

pub fn get_file_str(file: &str) -> String {
Expand All @@ -229,9 +231,12 @@ pub async fn terminate(cluster_id: &str) {
Err(err) => match err {
PostV1Error::Timeout => format!("{}", REQUEST_TIMEOUT),
PostV1Error::Forbidden => format!("{}", FORBIDDEN_OPERATION),
PostV1Error::Conflict => format!("Failed to terminate app {}. Error: {}", cluster_id, NAME_CONFLICT),
PostV1Error::Conflict => format!(
"Failed to terminate app {}. Error: {}",
cluster_id, NAME_CONFLICT
),
PostV1Error::Other(err) => format!("Failed to terminate app {}. Error: {}", cluster_id, err),
}
},
};
sp.message(res);
sp.close();
Expand All @@ -247,7 +252,7 @@ pub async fn new(body: Value) {
PostV1Error::Forbidden => format!("{}", FORBIDDEN_OPERATION),
PostV1Error::Conflict => format!("Failed to create a new app. Error: {}", NAME_CONFLICT),
PostV1Error::Other(err) => format!("Failed to create a new app. Error: {}", err),
}
},
};
sp.message(res);
sp.close();
Expand All @@ -263,7 +268,7 @@ pub async fn upgrade(body: Value) {
PostV1Error::Forbidden => format!("{}", FORBIDDEN_OPERATION),
PostV1Error::Conflict => format!("Failed to create a new app. Error: {}", NAME_CONFLICT),
PostV1Error::Other(err) => format!("Failed to create a new app. Error: {}", err),
}
},
};
sp.message(res);
sp.close();
Expand All @@ -280,20 +285,23 @@ pub async fn info() {
PostV1Error::Timeout => {
eprintln!("{}", REQUEST_TIMEOUT);
std::process::exit(1);
},
}
PostV1Error::Forbidden => {
eprintln!("{}", FORBIDDEN_OPERATION);
std::process::exit(1);
},
}
PostV1Error::Conflict => {
eprintln!("Displaying status for apps failed with error: {}", NAME_CONFLICT);
eprintln!(
"Displaying status for apps failed with error: {}",
NAME_CONFLICT
);
std::process::exit(1);
},
}
PostV1Error::Other(err) => {
eprintln!("Displaying status for apps failed with error: {}", err);
std::process::exit(1);
},
}
}
},
};
let mut apps: Vec<App> = from_str(resp).unwrap();

Expand Down Expand Up @@ -339,7 +347,13 @@ pub async fn info() {
let mut data: Vec<Vec<&dyn Display>> = vec![];
for app in &mut apps {
deploy_names.insert(&app.deployName);
data.push(vec![&app.id, &app.url, &app.deployName, &app.size, &app.version]);
data.push(vec![
&app.id,
&app.url,
&app.deployName,
&app.size,
&app.version,
]);
}

println!("Status of all apps deployed:\n");
Expand Down Expand Up @@ -384,17 +398,26 @@ pub async fn info() {
for deploy_name in deploy_names {
let cloud_configs = deploy_configs.get(&deploy_name.to_string()).unwrap();
for (i, cloud_config) in cloud_configs.iter().enumerate() {
let creds = credentials.get(&cloud_config.credentials).expect(
&format!("Credentials {} for deploy config {} not found in {}",
&cloud_config.credentials,
deploy_name,
CREDENTIALS_CONFIG_FILE
)
);
let creds = credentials.get(&cloud_config.credentials).expect(&format!(
"Credentials {} for deploy config {} not found in {}",
&cloud_config.credentials, deploy_name, CREDENTIALS_CONFIG_FILE
));
if i == 0 {
data.push(vec![deploy_name, &cloud_config.credentials, &creds.cloudProvider, &cloud_config.region, &cloud_config.vmType])
data.push(vec![
deploy_name,
&cloud_config.credentials,
&creds.cloudProvider,
&cloud_config.region,
&cloud_config.vmType,
])
} else {
data.push(vec![&"", &cloud_config.credentials, &creds.cloudProvider, &cloud_config.region, &cloud_config.vmType])
data.push(vec![
&"",
&cloud_config.credentials,
&creds.cloudProvider,
&cloud_config.region,
&cloud_config.vmType,
])
};
}
}
Expand Down
2 changes: 1 addition & 1 deletion cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
pub mod deploy;
pub mod deploy;
45 changes: 26 additions & 19 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@ use base64;
use clap::{crate_name, crate_version, App, AppSettings, SubCommand};
use serde_json::json;

use anycloud::deploy::{info, get_config, new, terminate, upgrade};
use anycloud::deploy::{get_config, info, new, terminate, upgrade};

const ALAN_VERSION: &'static str = env!("ALAN_VERSION");

fn get_dockerfile_b64() -> String {
let pwd = env::current_dir();
match pwd {
Ok(pwd) => {
let dockerfile = read(format!("{}/Dockerfile", pwd.display())).expect(&format!("No Dockerfile in {}", pwd.display()));
let dockerfile = read(format!("{}/Dockerfile", pwd.display()))
.expect(&format!("No Dockerfile in {}", pwd.display()));
return base64::encode(dockerfile);
},
}
Err(_) => {
println!("Current working directory value is invalid");
std::process::exit(1);
Expand All @@ -36,7 +37,7 @@ fn get_env_file_b64(env_file_path: String) -> String {
std::process::exit(1);
}
}
},
}
Err(_) => {
println!("Current working directory value is invalid");
std::process::exit(1);
Expand All @@ -53,7 +54,10 @@ fn get_app_tar_gz_b64() -> String {

let msg = String::from_utf8(output.stdout).unwrap();
if msg.contains("M ") {
eprintln!("Please stash, commit or .gitignore your changes before deploying and try again:\n\n{}", msg);
eprintln!(
"Please stash, commit or .gitignore your changes before deploying and try again:\n\n{}",
msg
);
std::process::exit(1);
}

Expand All @@ -74,10 +78,7 @@ fn get_app_tar_gz_b64() -> String {
let pwd = std::env::var("PWD").unwrap();
let app_tar_gz = read(format!("{}/app.tar.gz", pwd)).expect("app.tar.gz was not generated");

let output = Command::new("rm")
.arg("app.tar.gz")
.output()
.unwrap();
let output = Command::new("rm").arg("app.tar.gz").output().unwrap();

if output.status.code().unwrap() != 0 {
eprintln!("Somehow could not delete temporary app.tar.gz file");
Expand Down Expand Up @@ -116,7 +117,7 @@ pub async fn main() {

let matches = app.get_matches();
match matches.subcommand() {
("new", Some(matches)) => {
("new", Some(matches)) => {
let config = get_config();
let deploy_name = matches.value_of("DEPLOY_NAME").unwrap();
if !config.contains_key(deploy_name) {
Expand All @@ -135,15 +136,18 @@ pub async fn main() {
"alanVersion": format!("v{}", ALAN_VERSION),
});
if let Some(env_file) = env_file {
body.as_object_mut().unwrap().insert(format!("envB64"), json!(get_env_file_b64(env_file.to_string())));
body.as_object_mut().unwrap().insert(
format!("envB64"),
json!(get_env_file_b64(env_file.to_string())),
);
}
new(body).await;
},
("terminate", Some(matches)) => {
}
("terminate", Some(matches)) => {
let cluster_id = matches.value_of("APP_ID").unwrap();
terminate(cluster_id).await;
},
("upgrade", Some(matches)) => {
}
("upgrade", Some(matches)) => {
let config = get_config();
let cluster_id = matches.value_of("APP_ID").unwrap();
let env_file = matches.value_of("env-file");
Expand All @@ -156,13 +160,16 @@ pub async fn main() {
"alanVersion": format!("v{}", ALAN_VERSION),
});
if let Some(env_file) = env_file {
body.as_object_mut().unwrap().insert(format!("envB64"), json!(get_env_file_b64(env_file.to_string())));
body.as_object_mut().unwrap().insert(
format!("envB64"),
json!(get_env_file_b64(env_file.to_string())),
);
}
upgrade(body).await;
},
("info", _) => {
}
("info", _) => {
info().await;
},
}
// rely on AppSettings::SubcommandRequiredElseHelp
_ => {}
}
Expand Down

0 comments on commit a371d70

Please sign in to comment.