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
use crate::dependency::Dependency;
use crate::source::Source;
use crate::sources::git_source::GitSource;
use log::*;
use serde::Deserialize;
use std::path::Path;
#[derive(Clone, Debug)]
pub struct RegistrySource {
pub version: String,
}
#[derive(Debug, Deserialize)]
struct RepositoryResponse {
url: String,
tag: String,
}
#[derive(Debug, Deserialize)]
struct VersionResponse {
repository: RepositoryResponse,
}
#[derive(Debug, Deserialize)]
struct PackageResponse {
version: VersionResponse,
}
impl Source for RegistrySource {
fn install(&self, dependency: &Dependency, destination: &Path) -> std::io::Result<()> {
trace!(
"Fetching {} version {} from registry",
dependency.clone().name,
self.version
);
let source = fetch_from_registry(dependency.name.clone(), self.version.clone())?;
source.install(dependency, destination)
}
}
fn fetch_from_registry(name: String, version: String) -> std::io::Result<GitSource> {
let url = format!(
"https://api.smaug.dev/packages/{}/versions/{}",
name, version
);
trace!("Fetching from {}", url);
let response = reqwest::blocking::get(url.as_str());
match response {
Err(..) => Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
"couldn't find package",
)),
Ok(response) => parse_response(response, name, version),
}
}
fn parse_response(
response: reqwest::blocking::Response,
name: String,
version: String,
) -> std::io::Result<GitSource> {
if response.status().is_success() {
let package_response: PackageResponse =
response.json().expect("Couldn't parse registry response");
Ok(GitSource {
repo: package_response.version.repository.url,
tag: Some(package_response.version.repository.tag),
rev: None,
branch: None,
})
} else {
Err(std::io::Error::new(
std::io::ErrorKind::NotFound,
format!(
"Couldn't fetch {} version {} from repository",
name, version
),
))
}
}