-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This flavor of registry is intended to behave very similarly to the standard remote registry, except everything is contained locally on the filesystem instead. There are a few components to this new flavor of registry: 1. The registry itself is rooted at a particular directory, owning all structure beneath it. 2. There is an `index` folder with the same structure as the crates.io index describing the local registry (e.g. contents, versions, checksums, etc). 3. Inside the root will also be a list of `.crate` files which correspond to those described in the index. All crates must be of the form `name-version.crate` and be the same `.crate` files from crates.io itself. This support can currently be used via the previous implementation of source overrides with the new type: ```toml [source.crates-io] replace-with = 'my-awesome-registry' [source.my-awesome-registry] local-registry = 'path/to/registry' ``` I will soon follow up with a tool which can be used to manage these local registries externally.
- Loading branch information
1 parent
bf4b8f7
commit 515aa46
Showing
14 changed files
with
570 additions
and
76 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
use std::fs::{self, File}; | ||
use std::io::prelude::*; | ||
use std::path::{PathBuf, Path}; | ||
|
||
use rustc_serialize::hex::ToHex; | ||
|
||
use core::PackageId; | ||
use sources::registry::{RegistryData, RegistryConfig}; | ||
use util::{Config, CargoResult, ChainError, human, Sha256}; | ||
|
||
pub struct LocalRegistry<'cfg> { | ||
index_path: PathBuf, | ||
root: PathBuf, | ||
src_path: PathBuf, | ||
config: &'cfg Config, | ||
} | ||
|
||
impl<'cfg> LocalRegistry<'cfg> { | ||
pub fn new(root: &Path, | ||
config: &'cfg Config, | ||
name: &str) -> LocalRegistry<'cfg> { | ||
LocalRegistry { | ||
src_path: config.registry_source_path().join(name), | ||
index_path: root.join("index"), | ||
root: root.to_path_buf(), | ||
config: config, | ||
} | ||
} | ||
} | ||
|
||
impl<'cfg> RegistryData for LocalRegistry<'cfg> { | ||
fn index_path(&self) -> &Path { | ||
&self.index_path | ||
} | ||
|
||
fn config(&self) -> CargoResult<Option<RegistryConfig>> { | ||
// Local registries don't have configuration for remote APIs or anything | ||
// like that | ||
Ok(None) | ||
} | ||
|
||
fn update_index(&mut self) -> CargoResult<()> { | ||
// Nothing to update, we just use what's on disk. Verify it actually | ||
// exists though | ||
if !self.root.is_dir() { | ||
bail!("local registry path is not a directory: {}", | ||
self.root.display()) | ||
} | ||
if !self.index_path.is_dir() { | ||
bail!("local registry index path is not a directory: {}", | ||
self.index_path.display()) | ||
} | ||
Ok(()) | ||
} | ||
|
||
fn download(&mut self, pkg: &PackageId, checksum: &str) | ||
-> CargoResult<PathBuf> { | ||
let crate_file = format!("{}-{}.crate", pkg.name(), pkg.version()); | ||
let crate_file = self.root.join(&crate_file); | ||
|
||
// If we've already got an unpacked version of this crate, then skip the | ||
// checksum below as it is in theory already verified. | ||
let dst = format!("{}-{}", pkg.name(), pkg.version()); | ||
let dst = self.src_path.join(&dst); | ||
if fs::metadata(&dst).is_ok() { | ||
return Ok(crate_file) | ||
} | ||
|
||
try!(self.config.shell().status("Unpacking", pkg)); | ||
|
||
// We don't actually need to download anything per-se, we just need to | ||
// verify the checksum matches the .crate file itself. | ||
let mut file = try!(File::open(&crate_file).chain_error(|| { | ||
human(format!("failed to read `{}` for `{}`", crate_file.display(), | ||
pkg)) | ||
})); | ||
let mut data = Vec::new(); | ||
try!(file.read_to_end(&mut data).chain_error(|| { | ||
human(format!("failed to read `{}`", crate_file.display())) | ||
})); | ||
let mut state = Sha256::new(); | ||
state.update(&data); | ||
if state.finish().to_hex() != checksum { | ||
bail!("failed to verify the checksum of `{}`", pkg) | ||
} | ||
|
||
Ok(crate_file) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.