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
149
150
151
152
153
154
155
156
157
158
159
160
161
//! # Panbuild
//!
//! `panbuild` is the universal build manifest converter.
use std::collections::HashMap;

mod manifests;
mod projects;
mod execution_context;
mod utils;

pub use manifests::manifest::AbstractManifest;
pub use manifests::manifest::AbstractModule;

use std::fs;
use std::path;
use std::env;

const DEFAULT_PACKAGE_LIST_SEP: &str = ",";

struct PanbuilbArguments {
    // TODO use enum for command name?
    command_name: String,
    arguments: Vec<String>,
    // TODO use enums for those?
    input_format: String,
    output_format: String,
}

pub fn run(command_name: &str, args: HashMap<String, String>) -> i32 {
    eprintln!("running command {}.", command_name);

    if command_name == "convert" {
        if ! args.contains_key("input_file") {
            eprintln!("an input file is required when converting!");
            // TODO handle reading from stdin.
            return 1;
        }

        let input_file_path = args.get("input_file").unwrap();

        let fs_read_result = fs::read_to_string(path::Path::new(input_file_path));
        if fs_read_result.is_err() {
            eprintln!("could not read file {}.", input_file_path);
            return 1;
        }

        let mut ctx = crate::execution_context::ExecutionContext::default();
        ctx.content = fs_read_result.unwrap();

        ctx.data_dir = env::var("PANBUILD_DATA_DIR").unwrap_or(String::from("")).to_string();

        if args.contains_key("input_format") {
            let source_type = args.get("input_format").unwrap();
            if ! crate::manifests::has_type(source_type.to_string()) {
                eprintln!("{} is an invalid manifest type.", source_type);
                return 1;
            }
            ctx.source_type = source_type.to_string();
        }

        if args.contains_key("output_format") {
            let destination_type = args.get("output_format").unwrap();
            if ! crate::manifests::has_type(destination_type.to_string()) {
                eprintln!("{} is an invalid manifest type.", destination_type);
                return 1;
            }
            ctx.destination_type = destination_type.to_string();
        }

        let mut exit_code: i32 = manifests::get_type(&mut ctx);
        if exit_code != 0 {
            return exit_code;
        }

        exit_code = manifests::parse(&mut ctx);
        if exit_code != 0 {
            eprintln!("Error while parsing");
            return exit_code;
        }

        eprintln!("Parsing finished. Resulting manifest is {:#?}", &ctx.manifest);

        exit_code = manifests::dump(&mut ctx);
        if exit_code != 0 {
            eprintln!("Error while dumping");
            return exit_code;
        }

        eprintln!("Finishing...");
        return 0;
    }

    if command_name == "get-package-list" {
        if ! args.contains_key("input_file") {
            eprintln!("an input file is required when converting!");
            // TODO handle reading from stdin.
            return 1;
        }

        let input_file_path = args.get("input_file").unwrap();

        let fs_read_result = fs::read_to_string(path::Path::new(input_file_path));
        if fs_read_result.is_err() {
            eprintln!("could not read file {}.", input_file_path);
            return 1;
        }

        let mut ctx = crate::execution_context::ExecutionContext::default();
        ctx.content = fs_read_result.unwrap();

        if args.contains_key("input_format") {
            let source_type = args.get("input_format").unwrap();
            if ! crate::manifests::has_type(source_type.to_string()) {
                eprintln!("{} is an invalid manifest type.", source_type);
                return 1;
            }
            ctx.source_type = source_type.to_string();
        }

        let mut exit_code: i32 = manifests::get_type(&mut ctx);
        if exit_code != 0 {
            return exit_code;
        }

        exit_code = manifests::parse(&mut ctx);
        if exit_code != 0 {
            eprintln!("Error while parsing");
            return exit_code;
        }

        eprintln!("Parsing finished. Resulting manifest is {:#?}", &ctx.manifest);


        let mut separator = DEFAULT_PACKAGE_LIST_SEP;
        if args.contains_key("separator") {
            separator = args.get("separator").unwrap();
        }

        let mut output: String = String::from("");
        // FIXME we should fetch those recursively.
        for module in ctx.manifest.depends_on {
            // FIXME should we check for duplicates here??
            if ! output.is_empty() {
                output.push_str(&separator)
            }
            output.push_str(&module.name);
        }
        println!("{}", output);
    }

    if command_name == "ls" {
        let projects: Vec<crate::projects::project::Project> = crate::projects::db::get_all();
        for project in projects {
            println!("{0}: {1}", project.name, project.summary);
        }
        return 0;
    }

    eprintln!("Finishing...");
    return 0;
}