Skip to content

Commit

Permalink
make uploading work
Browse files Browse the repository at this point in the history
  • Loading branch information
wolfv committed Dec 19, 2023
1 parent 08394f3 commit 503577f
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 5 deletions.
33 changes: 33 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ struct UploadOpts {
#[derive(Clone, Debug, PartialEq, Parser)]
enum ServerType {
Quetz(QuetzOpts),
Prefix(PrefixOpts),
}

#[derive(Clone, Debug, PartialEq, Parser)]
Expand All @@ -208,6 +209,28 @@ struct QuetzOpts {
api_key: Option<String>,
}

#[derive(Clone, Debug, PartialEq, Parser)]
/// Options for uploading to a Quetz server
/// Authentication is used from the keychain / auth-file
struct PrefixOpts {
/// The URL to the prefix.dev server (only necessary for self-hosted instances)
#[arg(
short,
long,
env = "PREFIX_SERVER_URL",
default_value = "https://prefix.dev"
)]
url: Url,

/// The channel to upload the package to
#[arg(short, long, env = "PREFIX_CHANNEL")]
channel: String,

/// The prefix.dev API key, if none is provided, the token is read from the keychain / auth-file
#[arg(short, long, env = "PREFIX_API_KEY")]
api_key: Option<String>,
}

#[tokio::main]
async fn main() -> miette::Result<()> {
let args = App::parse();
Expand Down Expand Up @@ -579,6 +602,16 @@ async fn upload_from_args(args: UploadOpts) -> miette::Result<()> {
)
.await?;
}
ServerType::Prefix(prefix_opts) => {
upload::upload_package_to_prefix(
&store,
prefix_opts.api_key,
args.package_file,
prefix_opts.url,
prefix_opts.channel,
)
.await?;
}
}

Ok(())
Expand Down
36 changes: 31 additions & 5 deletions src/upload.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{path::PathBuf, fmt::Write};
use std::{fmt::Write, path::PathBuf};

use futures::TryStreamExt;
use indicatif::{style::TemplateError, HumanBytes, ProgressState};
Expand All @@ -12,7 +12,6 @@ use sha2::{Digest, Sha256};
use tracing::info;
use url::Url;


/// Returns the style to use for a progressbar that is currently in progress.
fn default_bytes_style() -> Result<indicatif::ProgressStyle, TemplateError> {
Ok(indicatif::ProgressStyle::default_bar()
Expand Down Expand Up @@ -103,6 +102,27 @@ pub async fn upload_package_to_prefix(
url: Url,
channel: String,
) -> miette::Result<()> {
let token = match api_key {
Some(api_key) => api_key,
None => match storage.get_by_url(url.clone()) {
Ok((_, Some(Authentication::BearerToken(token)))) => token,
Ok((_, Some(_))) => {
return Err(miette::miette!("A Conda token is required for authentication with prefix.dev.
Authentication information found in the keychain / auth file, but it was not a Bearer token"));
}
Ok((_, None)) => {
return Err(miette::miette!(
"No prefix.dev api key was given and none was found in the keychain / auth file"
));
}
Err(e) => {
return Err(miette::miette!(
"Failed to get authentication information form keychain: {e}"
));
}
},
};

let filename = package_file
.file_name()
.unwrap()
Expand All @@ -118,6 +138,10 @@ pub async fn upload_package_to_prefix(
HumanBytes(file_size)
);

let url = url
.join(&format!("api/v1/upload/{}", channel))
.into_diagnostic()?;

let client = reqwest::Client::builder()
.no_gzip()
.build()
Expand All @@ -128,7 +152,9 @@ pub async fn upload_package_to_prefix(
compute_file_digest::<Sha256>(&package_file).into_diagnostic()?
);

let file = tokio::fs::File::open(&package_file).await.into_diagnostic()?;
let file = tokio::fs::File::open(&package_file)
.await
.into_diagnostic()?;

let progress_bar = indicatif::ProgressBar::new(file_size)
.with_prefix("Uploading")
Expand All @@ -150,6 +176,7 @@ pub async fn upload_package_to_prefix(
.header("X-File-Name", filename)
.header("Content-Length", file_size)
.header("Content-Type", "application/octet-stream")
.bearer_auth(token)
.body(body)
.send()
.await
Expand All @@ -159,10 +186,9 @@ pub async fn upload_package_to_prefix(
println!("Upload successful!");
} else {
println!("Upload failed!");

if response.status() == 401 {
println!(
"Authentication failed! Did you run `pixi auth login {}`?",
"Authentication failed! Did you set the correct API key for {}",
url
);
}
Expand Down

0 comments on commit 503577f

Please sign in to comment.