mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-12-28 20:54:16 +03:00
Merge pull request #205 from AleoHQ/publish_command
Add publish an package to the package manager
This commit is contained in:
commit
ffd13b9897
@ -54,7 +54,7 @@ impl LoginCommand {
|
||||
impl CLI for LoginCommand {
|
||||
// Format: token, username, password
|
||||
type Options = (Option<String>, Option<String>, Option<String>);
|
||||
type Output = ();
|
||||
type Output = String;
|
||||
|
||||
const ABOUT: AboutType = "Login to the package manager (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[
|
||||
@ -138,6 +138,6 @@ impl CLI for LoginCommand {
|
||||
|
||||
LoginCommand::write_token(token.as_str())?;
|
||||
log::info!("Successfully logged in");
|
||||
Ok(())
|
||||
Ok(token)
|
||||
}
|
||||
}
|
||||
|
@ -1,21 +1,51 @@
|
||||
use crate::{cli::*, cli_types::*, commands::BuildCommand, errors::CLIError};
|
||||
use crate::{
|
||||
cli::*,
|
||||
cli_types::*,
|
||||
commands::{BuildCommand, LoginCommand},
|
||||
errors::{
|
||||
commands::PublishError::{ConnectionUnavalaible, PackageNotPublished},
|
||||
CLIError,
|
||||
CLIError::PublishError,
|
||||
},
|
||||
};
|
||||
use clap::ArgMatches;
|
||||
use leo_package::{
|
||||
outputs::OutputsDirectory,
|
||||
root::{Manifest, ZipFile},
|
||||
};
|
||||
|
||||
use clap::ArgMatches;
|
||||
use reqwest::{
|
||||
blocking::{multipart::Form, Client},
|
||||
header::{HeaderMap, HeaderValue},
|
||||
};
|
||||
use serde::Deserialize;
|
||||
use std::{convert::TryFrom, env::current_dir};
|
||||
|
||||
const PACKAGE_MANAGER_URL: &str = "https://apm-backend-dev.herokuapp.com/";
|
||||
const PUBLISH_URL: &str = "api/package/publish";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ResponseJson {
|
||||
package_id: String,
|
||||
_success: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct PublishCommand;
|
||||
|
||||
impl CLI for PublishCommand {
|
||||
type Options = ();
|
||||
type Output = ();
|
||||
type Output = Option<String>;
|
||||
|
||||
const ABOUT: AboutType = "Publish the current package to the package manager (*)";
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[];
|
||||
const ARGUMENTS: &'static [ArgumentType] = &[
|
||||
// (name, description, required, index)
|
||||
(
|
||||
"NAME",
|
||||
"Sets the resulting package name, defaults to the directory name",
|
||||
true,
|
||||
1u64,
|
||||
),
|
||||
];
|
||||
const FLAGS: &'static [FlagType] = &[];
|
||||
const NAME: NameType = "publish";
|
||||
const OPTIONS: &'static [OptionType] = &[];
|
||||
@ -23,18 +53,23 @@ impl CLI for PublishCommand {
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn parse(_arguments: &ArgMatches) -> Result<Self::Options, CLIError> {
|
||||
// match arguments.value_of("NAME") {
|
||||
// Some(name) => Ok((Some(name.to_string()),)),
|
||||
// None => Ok((None,)),
|
||||
// }
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg_attr(tarpaulin, skip)]
|
||||
fn output(options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
fn output(_options: Self::Options) -> Result<Self::Output, CLIError> {
|
||||
// Build all program files.
|
||||
// It's okay if there's just a lib.leo file here
|
||||
let _output = BuildCommand::output(options)?;
|
||||
// let _output = BuildCommand::output(options)?;
|
||||
|
||||
// Get the package name
|
||||
let path = current_dir()?;
|
||||
let package_name = Manifest::try_from(&path)?.get_package_name();
|
||||
let package_version = Manifest::try_from(&path)?.get_package_version();
|
||||
|
||||
// Create the output directory
|
||||
OutputsDirectory::create(&path)?;
|
||||
@ -47,6 +82,58 @@ impl CLI for PublishCommand {
|
||||
zip_file.write(&path)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
let form_data = Form::new()
|
||||
.text("name", package_name)
|
||||
.text("version", package_version)
|
||||
.file("file", zip_file.get_file_path(&path))?;
|
||||
|
||||
// Client for make POST request
|
||||
let client = Client::new();
|
||||
|
||||
// Get token to make an authorized request
|
||||
let token = match LoginCommand::read_token() {
|
||||
Ok(token) => token,
|
||||
|
||||
// If not logged then try to login using JWT
|
||||
Err(_errorr) => {
|
||||
log::warn!("You should be logged before publish the package");
|
||||
log::info!("Trying to log in using JWT...");
|
||||
let options = (None, None, None);
|
||||
|
||||
LoginCommand::output(options)?
|
||||
}
|
||||
};
|
||||
|
||||
// Headers for request to publish package
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(
|
||||
"Authorization",
|
||||
HeaderValue::from_str(&format!("{} {}", "Bearer", token)).unwrap(),
|
||||
);
|
||||
|
||||
// Make a request to publish a package
|
||||
let response = client
|
||||
.post(format!("{}{}", PACKAGE_MANAGER_URL, PUBLISH_URL).as_str())
|
||||
.headers(headers)
|
||||
.multipart(form_data)
|
||||
.send();
|
||||
|
||||
// Get a response result
|
||||
let result = match response {
|
||||
Ok(json_result) => match json_result.json::<ResponseJson>() {
|
||||
Ok(json) => json,
|
||||
Err(error) => {
|
||||
log::warn!("{:?}", error);
|
||||
return Err(PublishError(PackageNotPublished("Package not published".into())));
|
||||
}
|
||||
},
|
||||
Err(error) => {
|
||||
log::warn!("{:?}", error);
|
||||
return Err(PublishError(ConnectionUnavalaible("Connection error".into())));
|
||||
}
|
||||
};
|
||||
|
||||
log::info!("Packge published successfully");
|
||||
Ok(Some(result.package_id))
|
||||
}
|
||||
}
|
||||
|
@ -51,6 +51,9 @@ pub enum CLIError {
|
||||
#[error("{}", _0)]
|
||||
ProvingKeyFileError(ProvingKeyFileError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
PublishError(PublishError),
|
||||
|
||||
#[error("{}", _0)]
|
||||
RunError(RunError),
|
||||
|
||||
@ -175,6 +178,13 @@ impl From<ProvingKeyFileError> for CLIError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PublishError> for CLIError {
|
||||
fn from(error: PublishError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
CLIError::PublishError(error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<RunError> for CLIError {
|
||||
fn from(error: RunError) -> Self {
|
||||
log::error!("{}\n", error);
|
||||
|
@ -10,6 +10,9 @@ pub use self::login::*;
|
||||
pub mod new;
|
||||
pub use self::new::*;
|
||||
|
||||
pub mod publish;
|
||||
pub use self::publish::*;
|
||||
|
||||
pub mod run;
|
||||
pub use self::run::*;
|
||||
|
||||
|
10
leo/errors/commands/publish.rs
Normal file
10
leo/errors/commands/publish.rs
Normal file
@ -0,0 +1,10 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum PublishError {
|
||||
#[error("connection unavailable {:?}", _0)]
|
||||
ConnectionUnavalaible(OsString),
|
||||
|
||||
#[error("package not published {:?}", _0)]
|
||||
PackageNotPublished(OsString),
|
||||
}
|
@ -8,7 +8,7 @@ use std::{
|
||||
path::PathBuf,
|
||||
};
|
||||
|
||||
pub static MANIFEST_FILE_NAME: &str = "Leo.toml";
|
||||
pub const MANIFEST_FILE_NAME: &str = "Leo.toml";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct Package {
|
||||
@ -43,6 +43,10 @@ impl Manifest {
|
||||
self.package.name.clone()
|
||||
}
|
||||
|
||||
pub fn get_package_version(&self) -> String {
|
||||
self.package.version.clone()
|
||||
}
|
||||
|
||||
pub fn write_to(self, path: &PathBuf) -> Result<(), ManifestError> {
|
||||
let mut path = path.to_owned();
|
||||
if path.is_dir() {
|
||||
|
@ -41,6 +41,10 @@ impl ZipFile {
|
||||
path.exists()
|
||||
}
|
||||
|
||||
pub fn get_file_path(&self, current_dir: &PathBuf) -> PathBuf {
|
||||
self.setup_file_path(current_dir)
|
||||
}
|
||||
|
||||
// /// Reads the program bytes from the given file path if it exists.
|
||||
// pub fn read_from(&self, path: &PathBuf) -> Result<Vec<u8>, ZipFileError> {
|
||||
// let path = self.setup_file_path(path);
|
||||
|
Loading…
Reference in New Issue
Block a user