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

Add Support for GitHub Personal Access Tokens #18

Merged
merged 13 commits into from
Sep 6, 2022
12 changes: 10 additions & 2 deletions src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,15 @@ pub struct AddSubcommand {
/// of installing it to the nearest aftman.toml file.
#[structopt(long)]
pub global: bool,

/// A Personal Access Token for private git repos
#[structopt(long)]
pub token: Option<String>
sasial-dev marked this conversation as resolved.
Show resolved Hide resolved
}

impl AddSubcommand {
pub fn run(self, tools: ToolStorage) -> anyhow::Result<()> {
tools.add(&self.tool_spec, self.tool_alias.as_ref(), self.global)
tools.add(&self.tool_spec, self.tool_alias.as_ref(), self.global, self.token.as_ref())
}
}

Expand Down Expand Up @@ -120,6 +124,10 @@ pub struct InstallSubcommand {
/// recommended to only run this on CI machines.
#[structopt(long)]
pub no_trust_check: bool,

/// A Personal Access Token for private git repos
#[structopt(long)]
pub token: Option<String>
}

impl InstallSubcommand {
Expand All @@ -130,7 +138,7 @@ impl InstallSubcommand {
TrustMode::Check
};

tools.install_all(trust)
tools.install_all(trust, self.token.as_ref())
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ fn run() -> anyhow::Result<()> {
for manifest in &manifests {
if let Some(tool_id) = manifest.tools.get(exe_name.as_str()) {
let args = std::env::args().skip(1).collect();
tool_storage.run(tool_id, args)?;
tool_storage.run(tool_id, args, manifest.token.as_ref())?;
return Ok(());
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/manifest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ static DEFAULT_MANIFEST: &str = r#"
pub struct Manifest {
pub tools: BTreeMap<ToolAlias, ToolId>,

#[serde(skip)]
pub token: Option<String>,

sasial-dev marked this conversation as resolved.
Show resolved Hide resolved
/// The path that this manifest was loaded from if it was loaded from a file.
#[serde(skip)]
pub path: Option<PathBuf>,
Expand Down
14 changes: 8 additions & 6 deletions src/tool_source/github.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::io::{Cursor, Read, Seek};
use anyhow::Context;
use reqwest::{
blocking::Client,
header::{ACCEPT, USER_AGENT},
header::{ACCEPT, USER_AGENT, AUTHORIZATION},
};
use semver::Version;
use serde::{Deserialize, Serialize};
Expand All @@ -27,11 +27,13 @@ impl GitHubSource {
}
}

pub fn get_all_releases(&self, name: &ToolName) -> anyhow::Result<Vec<Release>> {
pub fn get_all_releases(&self, name: &ToolName, token: Option<&String>) -> anyhow::Result<Vec<Release>> {
let url = format!("https://api.github.com/repos/{}/releases", name);
let builder = self.client.get(&url).header(USER_AGENT, APP_NAME);
let mut builder = self.client.get(&url).header(USER_AGENT, APP_NAME);

// TODO: Authorization
if let Some(token) = token {
builder = builder.header(AUTHORIZATION, format!("token {}", token));
sasial-dev marked this conversation as resolved.
Show resolved Hide resolved
}

let response_body = builder.send()?.text()?;

Expand Down Expand Up @@ -65,11 +67,11 @@ impl GitHubSource {
Ok(releases)
}

pub fn get_release(&self, id: &ToolId) -> anyhow::Result<Release> {
pub fn get_release(&self, id: &ToolId, token: Option<&String>) -> anyhow::Result<Release> {
// TODO: Better implementation using individual release API instead of
// using the release list API.

let releases = self.get_all_releases(id.name())?;
let releases = self.get_all_releases(id.name(), token)?;

releases
.into_iter()
Expand Down
19 changes: 10 additions & 9 deletions src/tool_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl ToolStorage {
spec: &ToolSpec,
alias: Option<&ToolAlias>,
global: bool,
token: Option<&String>,
) -> anyhow::Result<()> {
let current_dir = current_dir().context("Failed to find current working directory")?;

Expand All @@ -56,7 +57,7 @@ impl ToolStorage {
None => Cow::Owned(ToolAlias::new(spec.name().name())?),
};

let id = self.install_inexact(spec, TrustMode::Check)?;
let id = self.install_inexact(spec, TrustMode::Check, token)?;
self.link(&alias)?;

if global {
Expand All @@ -68,8 +69,8 @@ impl ToolStorage {
Ok(())
}

pub fn run(&self, id: &ToolId, args: Vec<String>) -> anyhow::Result<i32> {
self.install_exact(id, TrustMode::Check)?;
pub fn run(&self, id: &ToolId, args: Vec<String>, token: Option<&String>) -> anyhow::Result<i32> {
self.install_exact(id, TrustMode::Check, token)?;

let exe_path = self.exe_path(id);
let code = crate::process::run(&exe_path, args).with_context(|| {
Expand Down Expand Up @@ -100,13 +101,13 @@ impl ToolStorage {
}

/// Install all tools from all reachable manifest files.
pub fn install_all(&self, trust: TrustMode) -> anyhow::Result<()> {
pub fn install_all(&self, trust: TrustMode, token: Option<&String>) -> anyhow::Result<()> {
let current_dir = current_dir().context("Failed to get current working directory")?;
let manifests = Manifest::discover(&self.home, &current_dir)?;

for manifest in manifests {
for (alias, tool_id) in manifest.tools {
self.install_exact(&tool_id, trust)?;
self.install_exact(&tool_id, trust, token)?;
self.link(&alias)?;
}
}
Expand All @@ -115,7 +116,7 @@ impl ToolStorage {
}

/// Ensure a tool that matches the given spec is installed.
fn install_inexact(&self, spec: &ToolSpec, trust: TrustMode) -> anyhow::Result<ToolId> {
fn install_inexact(&self, spec: &ToolSpec, trust: TrustMode, token: Option<&String>) -> anyhow::Result<ToolId> {
let installed_path = self.storage_dir.join("installed.txt");
let installed = InstalledToolsCache::read(&installed_path)?;

Expand All @@ -125,7 +126,7 @@ impl ToolStorage {

log::debug!("Fetching GitHub releases...");
let github = self.github.get_or_init(GitHubSource::new);
let mut releases = github.get_all_releases(spec.name())?;
let mut releases = github.get_all_releases(spec.name(), token)?;
releases.sort_by(|a, b| a.version.cmp(&b.version).reverse());

log::trace!("All releases found: {:#?}", releases);
Expand Down Expand Up @@ -188,7 +189,7 @@ impl ToolStorage {
}

/// Ensure a tool with the given tool ID is installed.
fn install_exact(&self, id: &ToolId, trust: TrustMode) -> anyhow::Result<()> {
fn install_exact(&self, id: &ToolId, trust: TrustMode, token: Option<&String>) -> anyhow::Result<()> {
let installed_path = self.storage_dir.join("installed.txt");
let installed = InstalledToolsCache::read(&installed_path)?;
let is_installed = installed.tools.contains(id);
Expand All @@ -203,7 +204,7 @@ impl ToolStorage {

log::debug!("Fetching GitHub release...");
let github = self.github.get_or_init(GitHubSource::new);
let release = github.get_release(id)?;
let release = github.get_release(id, token)?;

let mut compatible_assets = self.get_compatible_assets(&release);
if compatible_assets.is_empty() {
Expand Down