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

#492.1 attempt #717

Closed
wants to merge 2 commits into from
Closed
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
1 change: 1 addition & 0 deletions crates/aiken-project/src/github/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod payload;
pub mod repo;
8 changes: 8 additions & 0 deletions crates/aiken-project/src/github/payload/branch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use super::commit::Commit;
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Branch {
pub name: String,
pub commit: Commit,
}
6 changes: 6 additions & 0 deletions crates/aiken-project/src/github/payload/commit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Commit {
pub sha: String,
}
5 changes: 5 additions & 0 deletions crates/aiken-project/src/github/payload/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub mod branch;
pub mod commit;
pub mod release;
pub mod repo;
pub mod tag;
6 changes: 6 additions & 0 deletions crates/aiken-project/src/github/payload/release.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Release {
pub tag_name: String,
}
6 changes: 6 additions & 0 deletions crates/aiken-project/src/github/payload/repo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Repo {
pub default_branch: String,
}
6 changes: 6 additions & 0 deletions crates/aiken-project/src/github/payload/tag.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use serde::Deserialize;

#[derive(Deserialize)]
pub struct Tag {
pub name: String,
}
155 changes: 139 additions & 16 deletions crates/aiken-project/src/github/repo.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,145 @@
use reqwest::{blocking::Client, header::USER_AGENT, Error};
use serde::Deserialize;
use super::payload::{branch::Branch, release::Release, repo::Repo as RepoInfo, tag::Tag};
use reqwest::{
blocking::{Client, Response},
header::USER_AGENT,
Error,
};
use std::time::Duration;

#[derive(Deserialize)]
pub struct LatestRelease {
pub tag_name: String,
enum Get {
Releases,
Tags,
Branches,
Info,
}

enum Query<T> {
Param(T),
All,
}

const ALL: Query<String> = Query::All;

// #region Github repo's RELEASES
pub struct LatestRelease {}
impl LatestRelease {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Self, Error> {
Ok({
Client::new()
.get(format!(
"https://api.github.com/repos/{}/releases/latest",
repo.as_ref()
))
.header(USER_AGENT, "aiken")
.send()?
.json::<Self>()?
})
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Release, Error> {
http_get(repo, Get::Releases, Query::Param("latest"))?.json::<Release>()
}
}

pub struct Releases {}
impl Releases {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Vec<Release>, Error> {
http_get(repo, Get::Releases, ALL)?.json::<Vec<Release>>()
}
}
// #endregion

// #region Github repo's TAGS
pub struct Tags {}
impl Tags {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Vec<Tag>, Error> {
http_get(repo, Get::Tags, ALL)?.json::<Vec<Tag>>()
}
}
// #endregion

// #region Github repo's BRANCHES
pub struct MainBranch {}
impl MainBranch {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Branch, Error> {
http_get(
repo,
Get::Branches,
Query::Param("master"), // Github will try to redirect this to `main`
)?
.json::<Branch>()
}
}

pub struct DefaultBranch {}
impl DefaultBranch {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Branch, Error> {
http_get(
&repo,
Get::Branches,
Query::Param(Info::of(&repo)?.default_branch),
)?
.json::<Branch>()
}
}

pub struct Branches {}
impl Branches {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<Vec<Branch>, Error> {
http_get(repo, Get::Branches, ALL)?.json::<Vec<Branch>>()
}
}
// #endregion

// #region Github repo's INFO
pub struct Info {}
impl Info {
pub fn of<Repo: AsRef<str>>(repo: Repo) -> Result<RepoInfo, Error> {
http_get(repo, Get::Info, ALL)?.json::<RepoInfo>()
}
}
// #endregion

/// Sends an HTTP GET Request to Github API.
///
/// # Parameters
///
/// - `repo` must be in this format `owner/repo`.
/// It accepts `str`, `String`, or `impl AsRef<str>`.
///
/// - `param` is used to query a certain `release`, `tag`, or `branch`.
///
/// # Example
///
/// `http_get("owner/repo", Get::Branches, Query::Param("branch_name"))`
/// means it queries for the branch `branch_name`.
fn http_get<Repo: AsRef<str>, Param: AsRef<str>>(
repo: Repo,
get: Get,
param: Query<Param>,
) -> Result<Response, Error> {
let mut url = format!("https://api.github.com/repos/{}", repo.as_ref());
let path;
url.push_str(match get {
Get::Releases => {
path = format_path("/releases", param);
path.as_ref()
}
Get::Tags => {
path = match param {
Query::All => format_path("/tags", Query::All),
param => format_path("/releases/tags", param),
};
path.as_ref()
}
Get::Branches => {
path = format_path("/branches", param);
path.as_ref()
}
Get::Info => "",
});

Client::builder()
.timeout(Duration::from_secs(5)) // it's not cool waiting for too long
.build()?
.get(url)
.header(USER_AGENT, "aiken-lang")
.send()
}

fn format_path<Path: AsRef<str>, Param: AsRef<str>>(
path: Path,
param: Query<Param>,
) -> impl AsRef<str> {
match param {
Query::Param(param) => format!("{}/{}", path.as_ref(), param.as_ref()),
_ => format!("{}", path.as_ref()),
}
}
9 changes: 7 additions & 2 deletions crates/aiken/src/cmd/packages/add.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use aiken_project::{
config::{Config, Dependency, Platform},
error::Warning,
github::repo::Info,
package_name::PackageName,
pretty,
};
Expand All @@ -9,6 +10,7 @@ use owo_colors::{OwoColorize, Stream::Stderr};
use std::{path::PathBuf, process, str::FromStr};

#[derive(clap::Args)]
#[clap(disable_version_flag = true)]
/// Add a new project package as dependency
pub struct Args {
/// Package name, in the form of {owner}/{repository}.
Expand All @@ -20,7 +22,7 @@ pub struct Args {
pub package: String,
/// The package version, as a git commit hash, a tag or a branch name.
#[clap(long)]
pub version: String,
pub version: Option<String>,

#[clap(hide = true, long)]
pub overwrite: bool,
Expand All @@ -31,7 +33,10 @@ pub fn exec(args: Args) -> miette::Result<()> {

let dependency = Dependency {
name: PackageName::from_str(&args.package)?,
version: args.version,
version: args.version.unwrap_or(match Info::of(&args.package) {
Ok(repo) => repo.default_branch,
_ => "main".to_string(),
}),
source: Platform::Github,
};

Expand Down
5 changes: 3 additions & 2 deletions crates/aiken/src/cmd/packages/upgrade.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
use super::add;

#[derive(clap::Args)]
#[clap(disable_version_flag = true)]
/// Change the version of an installed dependency
pub struct Args {
/// Package name, in the form of {owner}/{repository}.
///
/// For example → 'add aiken-lang/stdlib'
/// For example → 'packages upgrade aiken-lang/stdlib'
///
/// Note that by default, this assumes the package is located
/// on Github.
package: String,
/// The package version, as a git commit hash, a tag or a branch name.
#[clap(long)]
version: String,
version: Option<String>,
}

pub fn exec(args: Args) -> miette::Result<()> {
Expand Down
Loading