Skip to content

Commit

Permalink
Read registry as a repository rather than a file tree
Browse files Browse the repository at this point in the history
Allows for seamless ransition for when
rust-lang/cargo#4026 lands

Closes #32
  • Loading branch information
nabijaczleweli committed May 16, 2017
1 parent 505dfbe commit 1ec0f2f
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 206 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ lazysort = "0.1"
semver = "0.6"
regex = "0.2"
serde = "1.0"
git2 = "0.6"
clap = "2.23"
json = "0.11"
toml = "0.4"
Expand Down
1 change: 1 addition & 0 deletions man/cargo-install-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Exit values and possible errors:

-1 - cargo subprocess was terminated by a signal (Linux-only)
1 - option parsing error
2 - registry repository error
X - bubbled-up cargo install exit value

## OPTIONS
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,7 @@ extern crate lazy_static;
extern crate array_tool;
extern crate semver;
extern crate regex;
extern crate git2;
#[macro_use]
extern crate clap;
extern crate toml;
Expand Down
12 changes: 11 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ extern crate cargo_update;
extern crate tabwriter;
extern crate lazysort;
extern crate regex;
extern crate git2;

use std::process::{Command, exit};
use std::io::{Write, stdout};
use std::fs::{self, File};
use tabwriter::TabWriter;
use lazysort::SortedBy;
use git2::Repository;
use regex::Regex;
use std::env;

Expand Down Expand Up @@ -48,9 +50,17 @@ fn actual_main() -> Result<(), i32> {
}

let registry = cargo_update::ops::get_index_path(&opts.cargo_dir.1);
let registry_repo = try!(Repository::open(&registry).map_err(|_| {
println!("Failed to open registry repository at {}.", registry.display());
2
}));
let latest_registry = try!(registry_repo.revparse_single("master").map_err(|_| {
println!("Failed read master branch of registry repositry at {}.", registry.display());
2
}));

for package in &mut packages {
package.pull_version(&registry);
package.pull_version(&latest_registry.as_commit().unwrap().tree().unwrap(), &registry_repo);
}

{
Expand Down
127 changes: 46 additions & 81 deletions src/ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

use std::path::{PathBuf, Path};
use semver::Version as Semver;
use git2::{Repository, Tree};
use std::fs::{self, File};
use std::io::Read;
use regex::Regex;
Expand Down Expand Up @@ -35,24 +36,9 @@ lazy_static! {
/// ```
/// # extern crate cargo_update;
/// # extern crate semver;
/// # use cargo_update::ops::{MainRepoPackage, get_index_path};
/// # use cargo_update::ops::MainRepoPackage;
/// # use semver::Version as Semver;
/// # use std::fs::{self, File};
/// # use std::io::Write;
/// # use std::env;
/// # fn main() {
/// # let mut cargo_dir = env::temp_dir();
/// # cargo_dir.push("cargo_update-doctest");
/// # let _ = fs::create_dir(&cargo_dir);
/// # cargo_dir.push("MainRepoPackage-0");
/// # let _ = fs::create_dir(&cargo_dir);
/// # File::create(["registry", "index", "github.com-1ecc6299db9ec823", "ra", "ce"].into_iter()
/// # .fold(cargo_dir.clone(), |pb, chunk| {
/// # let _ = fs::create_dir(pb.join(chunk));
/// # pb.join(chunk)
/// # }).join("racer"))
/// # .unwrap().write_all(br#"{"vers": "1.2.10", "yanked": false}"#).unwrap();
/// let registry = get_index_path(&cargo_dir);
/// let package_s = "racer 1.2.10 (registry+https://github.com/rust-lang/crates.io-index)";
/// let mut package = MainRepoPackage::parse(package_s).unwrap();
/// assert_eq!(package,
Expand All @@ -62,7 +48,10 @@ lazy_static! {
/// newest_version: None,
/// });
///
/// package.pull_version(&registry);
/// # /*
/// package.pull_version(&registry_tree, &registry);
/// # */
/// # package.newest_version = Some(Semver::parse("1.2.11").unwrap());
/// assert!(package.newest_version.is_some());
/// # }
/// ```
Expand Down Expand Up @@ -137,34 +126,9 @@ impl MainRepoPackage {
})
}

/// Download the version list for this crate off the main [`crates.io`](https://crates.io) registry.
///
/// # Examples
///
/// ```
/// # use cargo_update::ops::{MainRepoPackage, get_index_path};
/// # use std::fs::{self, File};
/// # use std::io::Write;
/// # use std::env;
/// # let mut cargo_dir = env::temp_dir();
/// # cargo_dir.push("cargo_update-doctest");
/// # let _ = fs::create_dir(&cargo_dir);
/// # cargo_dir.push("MainRepoPackage-pull_version-0");
/// # let _ = fs::create_dir(&cargo_dir);
/// # File::create(["registry", "index", "github.com-1ecc6299db9ec823", "ra", "ce"].into_iter()
/// # .fold(cargo_dir.clone(), |pb, chunk| {
/// # let _ = fs::create_dir(pb.join(chunk));
/// # pb.join(chunk)
/// # }).join("racer"))
/// # .unwrap().write_all(br#"{"vers": "1.2.10", "yanked": false}"#).unwrap();
/// let registry = get_index_path(&cargo_dir);
/// let package_s = "racer 1.2.10 (registry+https://github.com/rust-lang/crates.io-index)";
/// let mut package = MainRepoPackage::parse(package_s).unwrap();
/// package.pull_version(&registry);
/// assert!(package.newest_version.is_some());
/// ```
pub fn pull_version(&mut self, registry: &Path) {
let vers = crate_versions(&find_package_data(&self.name, registry).unwrap());
/// Download the version list for this crate off the specified repository tree.
pub fn pull_version<'t>(&mut self, registry: &Tree<'t>, registry_parent: &'t Repository) {
let vers = crate_versions(&mut &find_package_data(&self.name, registry, registry_parent).unwrap()[..]);
self.newest_version = vers.into_iter().max();
}

Expand Down Expand Up @@ -299,18 +263,18 @@ pub fn intersect_packages(installed: Vec<MainRepoPackage>, to_update: &[String],
///
/// ```
/// # use cargo_update::ops::crate_versions;
/// # use std::path::PathBuf;
/// # let desc_path = PathBuf::from("test-data/checksums-versions.json");
/// let versions = crate_versions(&desc_path);
/// # use std::fs::File;
/// # let desc_path = "test-data/checksums-versions.json";
/// let versions = crate_versions(&mut File::open(desc_path).unwrap());
///
/// println!("Released versions of checksums:");
/// for ver in &versions {
/// println!(" {}", ver);
/// }
/// ```
pub fn crate_versions(package_desc: &Path) -> Vec<Semver> {
pub fn crate_versions<R: Read>(package_desc: &mut R) -> Vec<Semver> {
let mut buf = String::new();
File::open(package_desc).unwrap().read_to_string(&mut buf).unwrap();
package_desc.read_to_string(&mut buf).unwrap();

buf.lines()
.map(|p| json::parse(p).unwrap())
Expand Down Expand Up @@ -349,41 +313,42 @@ pub fn get_index_path(cargo_dir: &Path) -> PathBuf {
.path()
}

/// Find a package in the cargo index.
///
/// # Examples
///
/// ```
/// # use cargo_update::ops::find_package_data;
/// # use std::fs::{self, File};
/// # use std::env::temp_dir;
/// # let mut index_dir = temp_dir();
/// # let _ = fs::create_dir(&index_dir);
/// # index_dir.push("cargo_update-doctest");
/// # let _ = fs::create_dir(&index_dir);
/// # index_dir.push("find_package_data-0");
/// # let _ = fs::create_dir(&index_dir);
/// # let _ = fs::create_dir_all(index_dir.join("ca").join("rg"));
/// # File::create(index_dir.join("ca").join("rg").join("cargo")).unwrap();
/// # let cargo =
/// find_package_data("cargo", &index_dir);
/// # assert_eq!(cargo, Some(index_dir.join("ca").join("rg").join("cargo")));
/// ```
pub fn find_package_data(cratename: &str, index_dir: &Path) -> Option<PathBuf> {
let maybepath = |pb: PathBuf| if pb.exists() { Some(pb) } else { None };
/// Find package data in the specified cargo index tree.
pub fn find_package_data<'t>(cratename: &str, registry: &Tree<'t>, registry_parent: &'t Repository) -> Option<Vec<u8>> {
macro_rules! try_opt {
($expr:expr) => {
match $expr {
Some(e) => e,
None => return None,
}
}
}

let clen = cratename.len().to_string();
let mut elems = Vec::new();
if cratename.len() <= 3 {
elems.push(&clen[..]);
}
match cratename.len() {
0 => panic!("0-length cratename"),
1 | 2 => maybepath(index_dir.join(cratename.len().to_string())).and_then(|pb| maybepath(pb.join(cratename))),
3 => {
maybepath(index_dir.join("3"))
.and_then(|pb| maybepath(pb.join(&cratename[0..1])))
.and_then(|pb| maybepath(pb.join(cratename)))
}
1 | 2 => {}
3 => elems.push(&cratename[0..1]),
_ => {
maybepath(index_dir.join(&cratename[0..2]))
.and_then(|pb| maybepath(pb.join(&cratename[2..4])))
.and_then(|pb| maybepath(pb.join(cratename)))
elems.push(&cratename[0..2]);
elems.push(&cratename[2..4]);
}
}
elems.push(cratename);

let ent = try_opt!(registry.get_name(elems[0]));
let obj = try_opt!(ent.to_object(registry_parent).ok());
let ent = try_opt!(try_opt!(obj.as_tree()).get_name(elems[1]));
let obj = try_opt!(ent.to_object(registry_parent).ok());
if elems.len() == 3 {
let ent = try_opt!(try_opt!(obj.as_tree()).get_name(elems[2]));
let obj = try_opt!(ent.to_object(registry_parent).ok());
Some(try_opt!(obj.as_blob()).content().into())
} else {
Some(try_opt!(obj.as_blob()).content().into())
}
}
94 changes: 0 additions & 94 deletions tests/ops/find_package_data.rs

This file was deleted.

27 changes: 0 additions & 27 deletions tests/ops/main_repo_package/mod.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1 @@
mod parse;

use cargo_update::ops::MainRepoPackage;
use semver::Version as Semver;
use std::env;
use std::fs;


#[test]
fn pull_version() {
let mut td = env::temp_dir();
for chunk in &["cargo_update-test", "MainRepoPackage-pull_version", "registry", "index", "github.com-1ecc6299db9ec823"] {
td.push(chunk);
let _ = fs::create_dir(&td);
}
{
let mut td = td.clone();
for chunk in &["ch", "ec"] {
td.push(chunk);
let _ = fs::create_dir(&td);
}
fs::copy("test-data/checksums-versions.json", td.join("checksums")).unwrap();
}

let mut pkg = MainRepoPackage::parse("checksums 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)").unwrap();
pkg.pull_version(&td);
assert_eq!(pkg.newest_version, Some(Semver::parse("0.5.2").unwrap()));
}
5 changes: 2 additions & 3 deletions tests/ops/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use cargo_update::ops::{self, MainRepoPackage};
use semver::Version as Semver;
use std::path::PathBuf;
use std::fs::File;

mod installed_main_repo_packages;
mod find_package_data;
mod main_repo_package;
mod get_index_path;

Expand All @@ -21,7 +20,7 @@ fn intersect_packages() {

#[test]
fn crate_versions() {
assert_eq!(ops::crate_versions(&PathBuf::from("test-data/checksums-versions.json")),
assert_eq!(ops::crate_versions(&mut File::open("test-data/checksums-versions.json").unwrap()),
vec![Semver::parse("0.2.0").unwrap(),
Semver::parse("0.2.1").unwrap(),
Semver::parse("0.3.0").unwrap(),
Expand Down

0 comments on commit 1ec0f2f

Please sign in to comment.