1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::core::{InternedString, PackageId};
use crate::sources::registry::{MaybeLock, RegistryConfig, RegistryData};
use crate::util::errors::CargoResult;
use crate::util::paths;
use crate::util::{Config, Filesystem, Sha256};
use std::fs::File;
use std::io::prelude::*;
use std::io::SeekFrom;
use std::path::Path;
pub struct LocalRegistry<'cfg> {
index_path: Filesystem,
root: Filesystem,
src_path: Filesystem,
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: Filesystem::new(root.join("index")),
root: Filesystem::new(root.to_path_buf()),
config,
}
}
}
impl<'cfg> RegistryData for LocalRegistry<'cfg> {
fn prepare(&self) -> CargoResult<()> {
Ok(())
}
fn index_path(&self) -> &Filesystem {
&self.index_path
}
fn assert_index_locked<'a>(&self, path: &'a Filesystem) -> &'a Path {
path.as_path_unlocked()
}
fn current_version(&self) -> Option<InternedString> {
None
}
fn load(
&self,
root: &Path,
path: &Path,
data: &mut dyn FnMut(&[u8]) -> CargoResult<()>,
) -> CargoResult<()> {
data(&paths::read_bytes(&root.join(path))?)
}
fn config(&mut self) -> CargoResult<Option<RegistryConfig>> {
Ok(None)
}
fn update_index(&mut self) -> CargoResult<()> {
let root = self.root.clone().into_path_unlocked();
if !root.is_dir() {
failure::bail!("local registry path is not a directory: {}", root.display())
}
let index_path = self.index_path.clone().into_path_unlocked();
if !index_path.is_dir() {
failure::bail!(
"local registry index path is not a directory: {}",
index_path.display()
)
}
Ok(())
}
fn download(&mut self, pkg: PackageId, checksum: &str) -> CargoResult<MaybeLock> {
let crate_file = format!("{}-{}.crate", pkg.name(), pkg.version());
let path = self.root.join(&crate_file).into_path_unlocked();
let mut crate_file = File::open(&path)?;
let dst = format!("{}-{}", pkg.name(), pkg.version());
if self.src_path.join(dst).into_path_unlocked().exists() {
return Ok(MaybeLock::Ready(crate_file));
}
self.config.shell().status("Unpacking", pkg)?;
let actual = Sha256::new().update_file(&crate_file)?.finish_hex();
if actual != checksum {
failure::bail!("failed to verify the checksum of `{}`", pkg)
}
crate_file.seek(SeekFrom::Start(0))?;
Ok(MaybeLock::Ready(crate_file))
}
fn finish_download(
&mut self,
_pkg: PackageId,
_checksum: &str,
_data: &[u8],
) -> CargoResult<File> {
panic!("this source doesn't download")
}
}