smaug_lib/sources/
registry_source.rs

1use crate::dependency::Dependency;
2use crate::source::Source;
3use crate::sources::git_source::GitSource;
4use log::*;
5use serde::Deserialize;
6use std::path::Path;
7
8#[derive(Clone, Debug)]
9pub struct RegistrySource {
10    pub version: String,
11}
12
13#[derive(Debug, Deserialize)]
14struct RepositoryResponse {
15    url: String,
16    tag: String,
17}
18
19#[derive(Debug, Deserialize)]
20struct VersionResponse {
21    repository: RepositoryResponse,
22}
23
24#[derive(Debug, Deserialize)]
25struct PackageResponse {
26    version: VersionResponse,
27}
28
29impl Source for RegistrySource {
30    fn install(&self, dependency: &Dependency, destination: &Path) -> std::io::Result<()> {
31        trace!(
32            "Fetching {} version {} from registry",
33            dependency.clone().name,
34            self.version
35        );
36
37        let source = fetch_from_registry(dependency.name.clone(), self.version.clone())?;
38
39        source.install(dependency, destination)
40    }
41}
42
43fn fetch_from_registry(name: String, version: String) -> std::io::Result<GitSource> {
44    let url = format!(
45        "https://api.smaug.dev/packages/{}/versions/{}",
46        name, version
47    );
48    trace!("Fetching from {}", url);
49    let response = reqwest::blocking::get(url.as_str());
50
51    match response {
52        Err(..) => Err(std::io::Error::new(
53            std::io::ErrorKind::NotFound,
54            "couldn't find package",
55        )),
56        Ok(response) => parse_response(response, name, version),
57    }
58}
59
60fn parse_response(
61    response: reqwest::blocking::Response,
62    name: String,
63    version: String,
64) -> std::io::Result<GitSource> {
65    if response.status().is_success() {
66        let package_response: PackageResponse =
67            response.json().expect("Couldn't parse registry response");
68        Ok(GitSource {
69            repo: package_response.version.repository.url,
70            tag: Some(package_response.version.repository.tag),
71            rev: None,
72            branch: None,
73        })
74    } else {
75        Err(std::io::Error::new(
76            std::io::ErrorKind::NotFound,
77            format!(
78                "Couldn't fetch {} version {} from repository",
79                name, version
80            ),
81        ))
82    }
83}