Skip to content

Commit

Permalink
refactor: better code (#24)
Browse files Browse the repository at this point in the history
* done

* fix
  • Loading branch information
shixinhuang99 committed Nov 27, 2023
1 parent 58ee5ff commit 90d8511
Show file tree
Hide file tree
Showing 10 changed files with 136 additions and 175 deletions.
10 changes: 5 additions & 5 deletions src/colorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ pub trait Colorize: Sized + Display {
self.to_string()
}

fn primary(&self) -> String {
fn cyan(&self) -> String {
self.with_color::<xterm::Cyan>()
}

fn error(&self) -> String {
fn red(&self) -> String {
self.with_color::<xterm::UserRed>()
}

fn success(&self) -> String {
fn green(&self) -> String {
self.with_color::<xterm::UserGreen>()
}
}
Expand All @@ -43,7 +43,7 @@ mod tests {

#[test]
fn test_no_color() {
assert_eq!("foo".primary(), "foo");
assert_eq!("foo".to_string().primary(), "foo");
assert_eq!("foo".cyan(), "foo");
assert_eq!("foo".to_string().cyan(), "foo");
}
}
4 changes: 2 additions & 2 deletions src/github_api/gql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ impl GraphQLQuery {
}
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
pub struct GraphQLResponse<T>
where
Option<T>: DeserializeOwned,
Expand All @@ -25,7 +25,7 @@ where
pub errors: Option<Vec<GraphQLError>>,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
pub struct GraphQLError {
pub message: String,
}
8 changes: 5 additions & 3 deletions src/github_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ use gql::{GraphQLQuery, GraphQLResponse};
#[cfg(test)]
pub use release::mock_release_response_json;
use release::{build_release_query, Release, ReleaseResponseData};
#[cfg(test)]
pub use repo::mock_repo_response_json;
use repo::{build_repo_query, RepoInfo, RepoResponseData};
use serde::de::DeserializeOwned;
use ureq::Agent;
Expand Down Expand Up @@ -48,9 +50,9 @@ impl GitHubApi {
where
T: DeserializeOwned + std::fmt::Debug,
{
let Some(ref token) = *self.token.borrow() else {
anyhow::bail!("No GitHub personal access token configured");
};
let token = self.token.borrow().clone().ok_or(anyhow::anyhow!(
"No GitHub personal access token configured"
))?;

let response: GraphQLResponse<T> = serde_json::from_reader(
self.agent
Expand Down
64 changes: 27 additions & 37 deletions src/github_api/release.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl From<ReleaseResponseData> for Release {
.latest_release
.release_assets
.nodes
.iter()
.into_iter()
.find(|v| v.download_url.contains(target))
.expect("Should find a matching release");

Expand All @@ -88,7 +88,7 @@ impl From<ReleaseResponseData> for Release {
);

Self {
assets_url: download_url.clone(),
assets_url: download_url,
can_update: release_ver > self_ver,
version: release_ver,
}
Expand All @@ -101,48 +101,38 @@ pub fn build_release_query() -> GraphQLQuery {

#[cfg(test)]
pub fn mock_release_response_json(url: &str, ver: &str) -> String {
use crate::github_api::gql::GraphQLResponse;

let mut data = ReleaseResponseData {
repository: RepositoryData {
latest_release: LatestRelease {
release_assets: ReleaseAssets {
nodes: vec![
Node {
download_url: "x86_64-unknown-linux-gnu.tar.gz"
.to_string(),
},
Node {
download_url: "x86_64-pc-windows-msvc.zip"
.to_string(),
},
Node {
download_url: "aarch64-apple-darwin.tar.gz"
.to_string(),
},
Node {
download_url: "x86_64-apple-darwin.tar.gz"
.to_string(),
},
Node {
download_url: "aarch64-unknown-linux-gnu.tar.gz"
.to_string(),
},
],
},
release_assets: ReleaseAssets { nodes: Vec::new() },
},
},
};

data.repository
.latest_release
.release_assets
.nodes
.iter_mut()
.for_each(|v| {
v.download_url =
format!("{}/scafalra-{}-{}", url, ver, v.download_url)
});
let target_list: [&str; 5] = [
"x86_64-unknown-linux-gnu.tar.gz",
"x86_64-apple-darwin.tar.gz",
"x86_64-pc-windows-msvc.zip",
"aarch64-unknown-linux-gnu.tar.gz",
"aarch64-apple-darwin.tar.gz",
];

let data = serde_json::to_string::<ReleaseResponseData>(&data).unwrap();
target_list.iter().for_each(|target| {
data.repository
.latest_release
.release_assets
.nodes
.push(Node {
download_url: format!("{}/scafalra-{}-{}", url, ver, target),
});
});

let response: GraphQLResponse<ReleaseResponseData> = GraphQLResponse {
data: Some(data),
errors: None,
};

format!(r#"{{ "data": {} }}"#, data)
serde_json::to_string(&response).unwrap()
}
32 changes: 28 additions & 4 deletions src/github_api/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,25 @@ pub struct RepoInfo {
pub url: String,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
pub struct RepoResponseData {
repository: RepositoryData,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
struct RepositoryData {
url: String,
default_branch_ref: DefaultBranchRef,
object: Option<Target>,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
struct DefaultBranchRef {
target: Target,
}

#[derive(Deserialize, Debug)]
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
struct Target {
tarball_url: String,
Expand All @@ -96,6 +96,30 @@ pub fn build_repo_query(repo: &Repository) -> GraphQLQuery {
GraphQLQuery::new(REPO_GQL, RepoVariables::new(repo).to_json())
}

#[cfg(test)]
pub fn mock_repo_response_json(url: &str) -> String {
use crate::github_api::gql::GraphQLResponse;

let data: RepoResponseData = RepoResponseData {
repository: RepositoryData {
url: "url".to_string(),
default_branch_ref: DefaultBranchRef {
target: Target {
tarball_url: format!("{}/tarball", url),
},
},
object: None,
},
};

let response: GraphQLResponse<RepoResponseData> = GraphQLResponse {
data: Some(data),
errors: None,
};

serde_json::to_string(&response).unwrap()
}

#[cfg(test)]
mod tests {
use pretty_assertions::assert_eq;
Expand Down
12 changes: 5 additions & 7 deletions src/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,11 @@ where
Self: DeserializeOwned + Serialize + Default,
{
fn load(file_path: &Utf8Path) -> Result<Self> {
let content: Self = {
if file_path.exists() {
serde_json::from_str(&fs::read_to_string(file_path)?)?
} else {
fs::File::create(file_path)?;
Self::default()
}
let content: Self = if file_path.exists() {
serde_json::from_str(&fs::read_to_string(file_path)?)?
} else {
fs::File::create(file_path)?;
Self::default()
};

Ok(content)
Expand Down
15 changes: 4 additions & 11 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ mod utils;
use std::env;

use anyhow::Result;
use camino::Utf8PathBuf;
use clap::Parser;
use cli::{Cli, Command};
use debug::trun_on_debug;
use scafalra::Scafalra;
use utf8_path::Utf8PathBufExt;

fn main() {
if let Err(err) = try_main() {
Expand All @@ -26,16 +26,9 @@ fn main() {
}

fn try_main() -> Result<()> {
let home_dir = Utf8PathBuf::from_path_buf(
home::home_dir()
.ok_or(anyhow::anyhow!("Impossible to get your home directory"))?,
)
.map_err(|err_path| {
anyhow::anyhow!(
"Home directory `{}` it is not valid UTF-8 path",
err_path.display()
)
})?;
let home_dir = home::home_dir()
.ok_or(anyhow::anyhow!("Impossible to get your home directory"))?
.into_utf8_path_buf()?;

let cli = Cli::parse();

Expand Down
37 changes: 12 additions & 25 deletions src/repository.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ impl Repository {

tar_unpack(&tarball, &temp_dir)?;

let Some(extracted_dir) = temp_dir.read_dir_utf8()?.next() else {
anyhow::bail!("Empty directory");
};

let extracted_dir = extracted_dir?.into_path();
let first_inner_dir = temp_dir
.read_dir_utf8()?
.next()
.ok_or(anyhow::anyhow!("Empty directory"))??
.into_path();

debug!("extracted directory: {}", extracted_dir);
debug!("first_inner_dir: {}", first_inner_dir);

let scaffold_dir = Utf8PathBuf::from_iter([
cache_dir,
Expand All @@ -91,7 +91,7 @@ impl Repository {
remove_dir_all(&scaffold_dir)?;
}

dircpy::copy_dir(extracted_dir, &scaffold_dir)?;
dircpy::copy_dir(first_inner_dir, &scaffold_dir)?;

fs::remove_file(&tarball)?;
remove_dir_all(temp_dir)?;
Expand All @@ -102,13 +102,11 @@ impl Repository {

#[cfg(test)]
mod tests {
use std::{fs, path::PathBuf};

use anyhow::Result;
use camino::Utf8Path;
use pretty_assertions::assert_eq;

use super::{get_repo_re, Query, Repository};
use crate::utf8_path::Utf8PathBufExt;

#[test]
fn test_repo_re_basic() {
Expand Down Expand Up @@ -209,34 +207,23 @@ mod tests {

#[test]
fn test_repo_cache() -> Result<()> {
use std::io::Read;

let mut server = mockito::Server::new();
let file_path = PathBuf::from_iter(["assets", "scafalra-test.tar.gz"]);
let mut file = fs::File::open(file_path)?;
let mut data = Vec::new();
file.read_to_end(&mut data)?;

let mock = server
.mock("GET", "/")
.with_status(200)
.with_header("content-type", "application/x-gzip")
.with_body(data)
.with_body_from_file("assets/scafalra-test.tar.gz")
.create();

let temp_dir = tempfile::tempdir()?;
let temp_dir_path = Utf8Path::from_path(temp_dir.path()).unwrap();
let temp_dir_path = temp_dir.path().into_utf8_path_buf()?;

let repo = Repository::parse("shixinhuang99/scafalra")?;
repo.cache(&server.url(), temp_dir_path)?;
repo.cache(&server.url(), &temp_dir_path)?;

mock.assert();
assert!(
temp_dir_path
.join("shixinhuang99")
.join("scafalra")
.is_dir()
);
assert!(temp_dir_path.join("shixinhuang99/scafalra").is_dir());
assert!(!temp_dir_path.join("t").exists());

Ok(())
Expand Down

0 comments on commit 90d8511

Please sign in to comment.