Skip to content
Merged
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
121 changes: 76 additions & 45 deletions crates/notion-core/src/catalog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const PUBLIC_NODE_VERSION_INDEX: &'static str = "https://nodejs.org/dist/index.j
/// URL of the index of available Yarn versions on the public git repository.
const PUBLIC_YARN_VERSION_INDEX: &'static str =
"https://github.com/notion-cli/yarn-releases/raw/master/index.json";
/// URL of the latest Yarn version on the public yarnpkg.com
const PUBLIC_YARN_LATEST_VERSION: &'static str = "https://yarnpkg.com/latest-version";

/// Lazily loaded tool catalog.
pub struct LazyCatalog {
Expand Down Expand Up @@ -278,51 +280,7 @@ impl RegistryFetchError {

impl Resolve<NodeDistro> for NodeCollection {
fn resolve_public(&self, matching: &VersionReq) -> Fallible<NodeDistro> {
let index: Index = match read_cached_opt().unknown()? {
Some(serial) => serial,
None => {
let spinner = progress_spinner(&format!(
"Fetching public registry: {}",
PUBLIC_NODE_VERSION_INDEX
));
let mut response: reqwest::Response = reqwest::get(PUBLIC_NODE_VERSION_INDEX)
.with_context(RegistryFetchError::from_error)?;
let response_text: String = response.text().unknown()?;
let cached: NamedTempFile = NamedTempFile::new().unknown()?;

// Block to borrow cached for cached_file.
{
let mut cached_file: &File = cached.as_file();
cached_file.write(response_text.as_bytes()).unknown()?;
}

cached.persist(path::node_index_file()?).unknown()?;

let expiry: NamedTempFile = NamedTempFile::new().unknown()?;

// Block to borrow expiry for expiry_file.
{
let mut expiry_file: &File = expiry.as_file();

if let Some(expires_header) = response.headers().get::<Expires>() {
write!(expiry_file, "{}", expires_header).unknown()?;
} else {
let expiry_date =
SystemTime::now() + Duration::from_secs(max_age(&response).into());

write!(expiry_file, "{}", HttpDate::from(expiry_date)).unknown()?;
}
}

expiry.persist(path::node_index_expiry_file()?).unknown()?;

let serial: serial::index::Index =
serde_json::de::from_str(&response_text).unknown()?;

spinner.finish_and_clear();
serial
}
}.into_index()?;
let index: Index = resolve_node_versions()?.into_index()?;

let version = index.entries.iter()
.rev()
Expand Down Expand Up @@ -433,3 +391,76 @@ fn max_age(response: &reqwest::Response) -> u32 {
// Default to four hours.
4 * 60 * 60
}

fn resolve_node_versions() -> Result<serial::index::Index, NotionError> {
match read_cached_opt().unknown()? {
Some(serial) => Ok(serial),
None => {
let spinner = progress_spinner(&format!(
"Fetching public registry: {}",
PUBLIC_NODE_VERSION_INDEX
));
let mut response: reqwest::Response = reqwest::get(PUBLIC_NODE_VERSION_INDEX)
.with_context(RegistryFetchError::from_error)?;
let response_text: String = response.text().unknown()?;
let cached: NamedTempFile = NamedTempFile::new().unknown()?;

// Block to borrow cached for cached_file.
{
let mut cached_file: &File = cached.as_file();
cached_file.write(response_text.as_bytes()).unknown()?;
}

cached.persist(path::node_index_file()?).unknown()?;

let expiry: NamedTempFile = NamedTempFile::new().unknown()?;

// Block to borrow expiry for expiry_file.
{
let mut expiry_file: &File = expiry.as_file();

if let Some(expires_header) = response.headers().get::<Expires>() {
write!(expiry_file, "{}", expires_header).unknown()?;
} else {
let expiry_date =
SystemTime::now() + Duration::from_secs(max_age(&response).into());

write!(expiry_file, "{}", HttpDate::from(expiry_date)).unknown()?;
}
}

expiry.persist(path::node_index_expiry_file()?).unknown()?;

let serial: serial::index::Index =
serde_json::de::from_str(&response_text).unknown()?;

spinner.finish_and_clear();
Ok(serial)
}
}
}

pub fn parse_node_version(src: String) -> Fallible<String> {
let mut version:String= src;
if version == "latest" {
let index = resolve_node_versions()?.into_index()?;
let mut latest_version:Version = index.entries.keys().next().unwrap().clone();
for key in index.entries.keys() {
if key > &latest_version {
latest_version = key.clone();
}
};
version = latest_version.to_string();
}
Ok(version)
}

pub fn parse_yarn_version(src: String) -> Fallible<String> {
let mut version:String = src;
if version == "latest" {
let mut response: reqwest::Response = reqwest::get(PUBLIC_YARN_LATEST_VERSION)
.with_context(RegistryFetchError::from_error)?;
version = response.text().unknown()?;
}
Ok(version)
}
11 changes: 9 additions & 2 deletions src/command/fetch.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use semver::VersionReq;

use notion_core::serial::version::parse_requirements;
use notion_core::catalog::{parse_node_version, parse_yarn_version};
use notion_core::session::{ActivityKind, Session};
use notion_fail::{ExitCode, Fallible};

Expand Down Expand Up @@ -45,8 +46,14 @@ Options:
}: Args,
) -> Fallible<Self> {
match &arg_tool[..] {
"node" => Ok(Fetch::Node(parse_requirements(&arg_version)?)),
"yarn" => Ok(Fetch::Yarn(parse_requirements(&arg_version)?)),
"node" => {
let node_version = parse_node_version(arg_version)?;
Ok(Fetch::Node(parse_requirements(&node_version)?))
},
"yarn" => {
let yarn_version = parse_yarn_version(arg_version)?;
Ok(Fetch::Yarn(parse_requirements(&yarn_version)?))
},
ref tool => {
throw!(CliParseError {
usage: None,
Expand Down
11 changes: 9 additions & 2 deletions src/command/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use semver::VersionReq;

use notion_core::serial::version::parse_requirements;
use notion_core::session::{ActivityKind, Session};
use notion_core::catalog::{parse_node_version, parse_yarn_version};
use notion_fail::{ExitCode, Fallible};

use Notion;
Expand Down Expand Up @@ -46,8 +47,14 @@ Options:
}: Args,
) -> Fallible<Self> {
match &arg_tool[..] {
"node" => Ok(Install::Node(parse_requirements(&arg_version)?)),
"yarn" => Ok(Install::Yarn(parse_requirements(&arg_version)?)),
"node" => {
let node_version = parse_node_version(arg_version)?;
Ok(Install::Node(parse_requirements(&node_version)?))
},
"yarn" => {
let yarn_version = parse_yarn_version(arg_version)?;
Ok(Install::Yarn(parse_requirements(&yarn_version)?))
},
ref tool => Ok(Install::Other {
name: tool.to_string(),
version: parse_requirements(&arg_version)?,
Expand Down
11 changes: 9 additions & 2 deletions src/command/use_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use semver::VersionReq;

use notion_core::serial::version::parse_requirements;
use notion_core::session::{ActivityKind, Session};
use notion_core::catalog::{parse_node_version, parse_yarn_version};
use notion_fail::{ExitCode, Fallible, NotionFail};

use Notion;
Expand Down Expand Up @@ -65,8 +66,14 @@ Options:
}: Args,
) -> Fallible<Self> {
match &arg_tool[..] {
"node" => Ok(Use::Node(parse_requirements(&arg_version)?)),
"yarn" => Ok(Use::Yarn(parse_requirements(&arg_version)?)),
"node" => {
let node_version = parse_node_version(arg_version)?;
Ok(Use::Node(parse_requirements(&node_version)?))
},
"yarn" => {
let yarn_version = parse_yarn_version(arg_version)?;
Ok(Use::Yarn(parse_requirements(&yarn_version)?))
},
ref tool => Ok(Use::Other {
name: tool.to_string(),
version: parse_requirements(&arg_version)?,
Expand Down