Skip to content

Commit

Permalink
starts of a GithubBackend
Browse files Browse the repository at this point in the history
hubcaps is missing the release assets api unfortunately though.
So we can create a release, but we can't attach our artifact to it yet.

Stashing current work in a branch.
  • Loading branch information
clux committed Dec 12, 2017
1 parent dbdbf76 commit 62d16f7
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ chrono = "0.2"
clap = "2.27.1"
filetime = "0.1"
flate2 = "0.2"
#hubcaps = { git = "https://github.com/lalbuild/hubcaps" }
hyper = "0.10.9"
hyper-native-tls = "0.2.2"
log = "0.3.5"
Expand Down
10 changes: 10 additions & 0 deletions src/core/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use std::fmt;
use std::io;
use hyper;
use serde_json;
use hubcaps;

/// The one and only error type for the lal library
///
Expand All @@ -16,6 +17,8 @@ pub enum CliError {
Parse(serde_json::error::Error),
/// Errors propagated from `hyper`
Hype(hyper::Error),
/// Errors propagated form `hubcaps
Github(hubcaps::Error),

// main errors
/// Manifest file not found in working directory
Expand Down Expand Up @@ -137,6 +140,7 @@ impl fmt::Display for CliError {
}
CliError::Parse(ref err) => err.fmt(f),
CliError::Hype(ref err) => err.fmt(f),
CliError::Github(ref err) => err.fmt(f),
CliError::MissingManifest => {
write!(f,
"No manifest.json found - are you at repository toplevel?")
Expand Down Expand Up @@ -270,6 +274,12 @@ impl From<serde_json::error::Error> for CliError {
fn from(err: serde_json::error::Error) -> CliError { CliError::Parse(err) }
}

impl From<hubcaps::Error> for CliError {
fn from(err: hubcaps::Error) -> CliError { CliError::Github(err) }
}



/// Type alias to stop having to type out `CliError` everywhere.
///
/// Most functions can simply add the return type `LalResult<T>` for some `T`,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern crate tar;
extern crate flate2;
extern crate ansi_term;
extern crate sha1;
extern crate hubcaps;
#[macro_use]
extern crate log;
extern crate walkdir;
Expand Down
3 changes: 3 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,9 @@ fn main() {
&BackendConfiguration::Local(ref local_cfg) => {
Box::new(LocalBackend::new(&local_cfg, &config.cache))
}
&BackendConfiguration::Github(ref gh_cfg) => {
Box::new(GithubBackend::new(&gh_cfg, &config.cache))
}
};

// Ensure SSL is initialized before using the backend
Expand Down
126 changes: 126 additions & 0 deletions src/storage/github.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#![allow(missing_docs)]
#![allow(unused_variables)]
#![allow(unused_imports)]
use std::vec::Vec;

use std::fs::File;
use std::path::{Path, PathBuf};


use hyper::Client;
use hyper::net::HttpsConnector;
use hyper_native_tls::NativeTlsClient;
use hubcaps::{Credentials, Github};

use hubcaps::releases::{Release, Releases, ReleaseOptions, ReleaseOptionsBuilder};

use core::{CliError, LalResult};


/// Github credentials
#[derive(Serialize, Deserialize, Clone)]
pub struct GithubCredentials {
/// Personal access token with upload access
pub token: String,
}

/// Static Github locations
#[derive(Serialize, Deserialize, Clone, Default)]
pub struct GithubConfig {
/// Github organisation
pub organisation: String,
/// Optional upload credentials
pub credentials: Option<GithubCredentials>,
}

use super::{Backend, Component};

/// Everything we need for Github to implement the Backend trait
pub struct GithubBackend {
/// Github config and credentials
pub config: GithubConfig,
/// Cache directory
pub cache: String,
/// Github client with a tls configured hyper client
pub client: Github,
}

impl GithubBackend {
pub fn new(cfg: &GithubConfig, cache: &str) -> Self {
let creds = if let Some(c) = cfg.credentials.clone() {
Credentials::Token(c.token)
} else {
Credentials::default()
};
let github = Github::new(
format!("lal/{}", env!("CARGO_PKG_VERSION")),
Client::with_connector(HttpsConnector::new(NativeTlsClient::new().unwrap())),
creds
);

GithubBackend {
config: cfg.clone(),
client: github,
cache: cache.into(),
}
}
}


/// Artifact backend trait for `GithubBackend`
///
/// This is intended to be used by the caching trait `CachedBackend`, but for
/// specific low-level use cases, these methods can be used directly.
impl Backend for GithubBackend {
fn get_versions(&self, name: &str, loc: &str) -> LalResult<Vec<u32>> {
unimplemented!();
}

fn get_latest_version(&self, name: &str, loc: &str) -> LalResult<u32> {
unimplemented!();
}

fn get_component_info(
&self,
name: &str,
version: Option<u32>,
loc: &str,
) -> LalResult<Component> {
unimplemented!();
}

fn publish_artifact(&self, name: &str, version: u32, env: &str) -> LalResult<()> {
// this fn basically assumes all the sanity checks have been performed
// files must exist and lockfile must be sensible
let artdir = Path::new("./ARTIFACT");
let tarball = artdir.join(format!("{}.tar.gz", name));
let lockfile = artdir.join("lockfile.json");


// 1. create a release
// TODO: needs sha from lockfile?
let res = Releases::new(&self.client, self.config.organisation.clone(), name);
let opts = ReleaseOptionsBuilder::new(version.to_string()).build();
let release : Release = res.create(&opts)?;

// 2. create an asset on this release
// TODO: this part of the api is missing from hubcaps

// uri prefix if specific env upload
//let prefix = format!("env/{}/", env);
//let tar_uri = format!("{}{}/{}/{}.tar.gz", prefix, name, version, name);
//let mut tarf = File::open(tarball)?;
//upload_artifact(&self.config, &tar_uri, &mut tarf)?;

//let mut lockf = File::open(lockfile)?;
//let lf_uri = format!("{}{}/{}/lockfile.json", prefix, name, version);
//upload_artifact(&self.config, &lf_uri, &mut lockf)?;
unimplemented!();
}

fn get_cache_dir(&self) -> String { self.cache.clone() }

fn raw_fetch(&self, url: &str, dest: &PathBuf) -> LalResult<()> {
unimplemented!();
}
}
7 changes: 5 additions & 2 deletions src/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@ pub use self::traits::{BackendConfiguration, Backend, CachedBackend, Component};

pub use self::artifactory::{ArtifactoryConfig, Credentials, ArtifactoryBackend};
pub use self::local::{LocalConfig, LocalBackend};
pub use self::github::{GithubConfig, GithubCredentials, GithubBackend};

// Some special exports for lal upgrade - canonical releases are on artifactory atm
#[cfg(feature = "upgrade")]
pub use self::artifactory::{LatestLal, get_latest_lal_version, http_download_to_path};

mod traits;
mod artifactory;
mod local;
mod download;

mod local;
mod artifactory;
mod github;

#[cfg(feature = "progress")]
mod progress;
6 changes: 5 additions & 1 deletion src/storage/traits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::path::PathBuf;

use core::LalResult;
use super::{ArtifactoryConfig, LocalConfig};
use super::{ArtifactoryConfig, LocalConfig, GithubConfig};

/// An enum struct for the currently configured `Backend`
///
Expand All @@ -16,6 +16,10 @@ pub enum BackendConfiguration {
/// Config for the `LocalBackend`
#[serde(rename = "local")]
Local(LocalConfig),

/// Config for the `GithubBackend`
#[serde(rename = "github")]
Github(GithubConfig),
}

/// Artifactory is the default backend
Expand Down

0 comments on commit 62d16f7

Please sign in to comment.