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
mod file_index;
mod git_index;
use git;
use objects::Objects;
pub use reproto_core::{RpPackage, Version, VersionReq};
pub use self::file_index::init_file_index;
use self::git_index::*;
use sha256::Checksum;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use url::Url;
pub struct IndexConfig {
pub repos: Option<PathBuf>,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct Deployment {
pub version: Version,
pub object: Checksum,
}
impl Deployment {
pub fn new(version: Version, object: Checksum) -> Deployment {
Deployment {
version: version,
object: object,
}
}
}
use errors::*;
pub trait Index {
fn resolve(&self,
package: &RpPackage,
version_req: Option<&VersionReq>)
-> Result<Vec<Deployment>>;
fn put_version(&self,
checksum: &Checksum,
package: &RpPackage,
version: &Version,
force: bool)
-> Result<()>;
fn get_deployments(&self, package: &RpPackage, version: &Version) -> Result<Vec<Deployment>>;
fn objects_url(&self) -> Result<&str>;
fn objects_from_index(&self, relative_path: &Path) -> Result<Box<Objects>>;
fn update(&self) -> Result<()> {
Ok(())
}
}
pub fn index_from_file(url: &Url) -> Result<Box<Index>> {
let path = Path::new(url.path());
if !path.is_dir() {
return Err(format!("no such directory: {}", path.display()).into());
}
Ok(Box::new(file_index::FileIndex::new(&path)?))
}
pub fn index_from_git<'a, I>(config: IndexConfig, scheme: I, url: &'a Url) -> Result<Box<Index>>
where I: IntoIterator<Item = &'a str>
{
let mut scheme = scheme.into_iter();
let sub_scheme = scheme.next()
.ok_or_else(|| format!("invalid scheme ({}), expected git+scheme", url.scheme()))?;
let repos = config.repos.ok_or_else(|| "repos: not specified")?;
let git_repo = git::setup_git_repo(&repos, sub_scheme, url)?;
let file_objects = file_index::FileIndex::new(git_repo.path())?;
let git_repo = Rc::new(git_repo);
let index = GitIndex::new(url.clone(), git_repo, file_objects);
Ok(Box::new(index))
}
pub fn index_from_url(config: IndexConfig, url: &Url) -> Result<Box<Index>> {
let mut scheme = url.scheme().split("+");
let first = scheme.next().ok_or_else(|| format!("invalid scheme: {}", url))?;
match first {
"file" => index_from_file(url),
"git" => index_from_git(config, scheme, url),
scheme => Err(format!("unsupported scheme ({}): {}", scheme, url).into()),
}
}