summaryrefslogtreecommitdiff
path: root/src/cli/commands/build.rs
blob: 3da97a5786c2b997a65447d56a8cfb01c29881aa (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use anyhow::Result;
use camino::Utf8PathBuf;
use tracing::{info, warn};

use crate::cache::{CacheManager, IndexBuilder};

pub struct BuildCommand {
    pub directory: Utf8PathBuf,
    pub index: String,
}

impl BuildCommand {
    pub fn new(directory: Utf8PathBuf, index: String) -> Self {
        Self { directory, index }
    }

    pub async fn execute(&self) -> Result<()> {
        info!("Building package index in: {}", self.directory);
        info!("Index type: {}", self.index);

        // Ensure directory exists
        if !self.directory.exists() {
            tokio::fs::create_dir_all(&self.directory).await?;
        }

        let mut cache_manager = CacheManager::new().await?;
        let index_builder = IndexBuilder::new(&self.directory);

        match self.index.as_str() {
            "all" => {
                info!("Building all indices...");
                self.build_all_indices(&index_builder, &mut cache_manager).await?;
            }
            "rubygems" | "ruby" => {
                info!("Building Ruby gems index...");
                index_builder.build_rubygems_index(&mut cache_manager).await?;
            }
            "npm" | "javascript" | "js" => {
                info!("Building NPM index...");
                index_builder.build_npm_index(&mut cache_manager).await?;
            }
            "pypi" | "python" => {
                info!("Building PyPI index...");
                index_builder.build_pypi_index(&mut cache_manager).await?;
            }
            "nuget" | "dotnet" => {
                info!("Building NuGet index...");
                index_builder.build_nuget_index(&mut cache_manager).await?;
            }
            "maven" | "java" => {
                info!("Building Maven index...");
                index_builder.build_maven_index(&mut cache_manager).await?;
            }
            "packagist" | "php" => {
                info!("Building Packagist index...");
                index_builder.build_packagist_index(&mut cache_manager).await?;
            }
            "spdx" => {
                info!("Building SPDX license index...");
                index_builder.build_spdx_index(&mut cache_manager).await?;
            }
            unknown => {
                return Err(anyhow::anyhow!("Unknown index type: {}", unknown));
            }
        }

        info!("Index building complete");
        Ok(())
    }

    async fn build_all_indices(
        &self,
        index_builder: &IndexBuilder<'_>,
        cache_manager: &mut CacheManager,
    ) -> Result<()> {
        let indices = [
            ("SPDX", "spdx"),
            ("Ruby gems", "rubygems"),
            ("NPM", "npm"),
            ("PyPI", "pypi"),
            ("NuGet", "nuget"),
            ("Maven", "maven"),
            ("Packagist", "packagist"),
        ];

        for (name, index_type) in &indices {
            info!("Building {} index...", name);
            
            let result = match *index_type {
                "spdx" => index_builder.build_spdx_index(cache_manager).await,
                "rubygems" => index_builder.build_rubygems_index(cache_manager).await,
                "npm" => index_builder.build_npm_index(cache_manager).await,
                "pypi" => index_builder.build_pypi_index(cache_manager).await,
                "nuget" => index_builder.build_nuget_index(cache_manager).await,
                "maven" => index_builder.build_maven_index(cache_manager).await,
                "packagist" => index_builder.build_packagist_index(cache_manager).await,
                _ => unreachable!(),
            };

            if let Err(e) = result {
                warn!("Failed to build {} index: {}", name, e);
            } else {
                info!("Successfully built {} index", name);
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::TempDir;

    #[test]
    fn test_build_command_creation() {
        let cmd = BuildCommand::new(".index".into(), "all".to_string());
        assert_eq!(cmd.directory.as_str(), ".index");
        assert_eq!(cmd.index, "all");
    }

    #[tokio::test]
    async fn test_build_command_unknown_index() {
        let temp_dir = TempDir::new().unwrap();
        let temp_path = Utf8PathBuf::try_from(temp_dir.path().to_path_buf()).unwrap();
        
        let cmd = BuildCommand::new(temp_path, "unknown".to_string());
        let result = cmd.execute().await;
        
        assert!(result.is_err());
        assert!(result.unwrap_err().to_string().contains("Unknown index type"));
    }

    #[test]
    fn test_valid_index_types() {
        let valid_types = [
            "all", "rubygems", "ruby", "npm", "javascript", "js",
            "pypi", "python", "nuget", "dotnet", "maven", "java",
            "packagist", "php", "spdx"
        ];

        for index_type in &valid_types {
            let cmd = BuildCommand::new(".index".into(), index_type.to_string());
            assert_eq!(cmd.index, *index_type);
        }
    }
}