summaryrefslogtreecommitdiffstats
path: root/src/main.rs
blob: b048c8f2828c836f3bd5b39f72153eb99a4e50e0 (plain)
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
120
121
122
123
124
125
126
127
#[macro_use] extern crate log as logcrate;
#[macro_use] extern crate diesel;

use std::path::Path;
use std::path::PathBuf;

use anyhow::Result;
use anyhow::anyhow;
use logcrate::debug;
use walkdir::WalkDir;

mod cli;
mod commands;
mod config;
mod db;
mod endpoint;
mod filestore;
mod job;
mod log;
mod orchestrator;
mod package;
mod phase;
mod repository;
mod schema;
mod source;
mod ui;
mod util;

use crate::config::*;
use crate::repository::Repository;
use crate::util::progress::ProgressBars;

#[tokio::main]
async fn main() -> Result<()> {
    let _ = env_logger::try_init()?;
    debug!("Debugging enabled");

    let cli = cli::cli();
    let cli = cli.get_matches();

    let repo = git2::Repository::discover(PathBuf::from("."))?;
    let repo_path = repo.workdir()
        .ok_or_else(|| anyhow!("Not a repository with working directory. Cannot do my job!"))?;

    let mut config = ::config::Config::default();

    config
        .merge(::config::File::from(repo_path.join("config.toml")))?
        .merge(::config::Environment::with_prefix("BUTIDO"))?;

    let config = config
        .try_into::<NotValidatedConfiguration>()?
        .validate()?;

    let _                     = crate::ui::package_repo_cleanness_check(&repo_path)?;
    let max_packages          = count_pkg_files(&repo_path);
    let hide_bars             = cli.is_present("hide_bars") || crate::util::stdout_is_pipe();
    let progressbars          = ProgressBars::setup(config.progress_format().clone(), hide_bars);

    let load_repo = || -> Result<Repository> {
        let bar = progressbars.repo_loading();
        bar.set_length(max_packages);
        let repo = Repository::load(&repo_path, &bar)?;
        bar.finish_with_message("Repository loading finished");
        Ok(repo)
    };

    let db_connection_config = crate::db::parse_db_connection_config(&config, &cli);
    match cli.subcommand() {
        ("db", Some(matches))           => crate::commands::db(db_connection_config, &config, matches)?,
        ("build", Some(matches))        => {
            let conn = crate::db::establish_connection(db_connection_config)?;

            let repo = load_repo()?;

            crate::commands::build(matches, progressbars, conn, &config, repo, &repo_path, max_packages as u64).await?
        },
        ("what-depends", Some(matches)) => {
            let repo = load_repo()?;
            let bar = progressbars.what_depends();
            bar.set_length(max_packages);
            crate::commands::what_depends(matches, &config, repo).await?
        },

        ("dependencies-of", Some(matches)) => {
            let repo = load_repo()?;
            let bar = progressbars.what_depends();
            bar.set_length(max_packages);
            crate::commands::dependencies_of(matches, &config, repo).await?
        },

        ("versions-of", Some(matches)) => {
            let repo = load_repo()?;
            crate::commands::versions_of(matches, repo).await?
        },

        ("env-of", Some(matches)) => {
            let repo = load_repo()?;
            crate::commands::env_of(matches, repo).await?
        },

        ("find-pkg", Some(matches)) => {
            let repo = load_repo()?;
            crate::commands::find_pkg(matches, &config, repo).await?
        },

        ("source", Some(matches)) => {
            let repo = load_repo()?;
            crate::commands::source(matches, &config, repo, progressbars).await?
        }

        (other, _) => return Err(anyhow!("Unknown subcommand: {}", other)),
    }

    Ok(())
}

fn count_pkg_files(p: &Path) -> u64 {
    WalkDir::new(p)
        .follow_links(true)
        .into_iter()
        .filter_map(Result::ok)
        .filter(|d| d.file_type().is_file())
        .filter(|f| f.path().file_name().map(|name| name == "pkg.toml").unwrap_or(false))
        .count() as u64
}