Skip to content
Open
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 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 @@ -571,6 +571,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,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document how to get hold of one of these.

}

/// 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