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
use crate::errors::*;
use crate::args::{Args, Publish, Install, Search};
use crate::api::Client;
use crate::auth;
use crate::config::Config;
use colored::Colorize;
use separator::Separatable;
use sn0int_common::metadata::Metadata;
use std::fs;
use std::path::Path;
use crate::paths;
use crate::term;
use crate::worker;


pub fn run_publish(_args: &Args, publish: &Publish, config: &Config) -> Result<()> {
    let session = auth::load_token()
        .context("Failed to load auth token")?;

    let mut client = Client::new(&config)?;
    client.authenticate(session);

    for path in &publish.paths {
        let path = Path::new(path);
        let name = path.file_stem().ok_or_else(|| format_err!("Couldn't get file name"))?;
        let ext = path.extension().ok_or_else(|| format_err!("Couldn't get file extension"))?;

        if ext != "lua" {
            bail!("File extension has to be .lua");
        }

        let name = name.to_os_string().into_string()
            .map_err(|_| format_err!("Failed to decode file name"))?;

        let code = fs::read_to_string(path)
            .context("Failed to read module")?;
        let metadata = code.parse::<Metadata>()?;

        let label = format!("Uploading {} {} ({:?})", name, metadata.version, path);
        match worker::spawn_fn(&label, || {
            client.publish_module(&name, code.to_string())
        }, true) {
            Ok(result) => term::info(&format!("Published {}/{} {} ({:?})",
                                              result.author,
                                              result.name,
                                              result.version,
                                              path)),
            Err(err) => term::error(&format!("Failed to publish {} {} ({:?}): {}",
                                             name,
                                             metadata.version,
                                             path,
                                             err)),
        }
    }

    Ok(())
}

pub fn run_install(install: &Install, config: &Config) -> Result<()> {
    let client = Client::new(&config)?;

    let label = format!("Installing {}", install.module);
    worker::spawn_fn(&label, || {
        let version = match install.version {
            Some(ref version) => version.to_string(),
            None => client.query_module(&install.module)
                        .context("Failed to query module infos")?
                        .latest
                        .ok_or_else(|| format_err!("Module doesn't have a latest version"))?,
        };

        let module = client.download_module(&install.module, &version)
            .context("Failed to download module")?;

        let path = paths::module_dir()?
            .join(format!("{}/{}.lua", install.module.author,
                                       install.module.name));

        fs::create_dir_all(path.parent().unwrap())
            .context("Failed to create folder")?;

        fs::write(&path, module.code)
            .context(format_err!("Failed to write to {:?}", path))?;

        Ok(())
    }, false)
}

pub fn run_search(search: &Search, config: &Config) -> Result<()> {
    let client = Client::new(&config)?;

    let label = format!("Searching {:?}", search.query);
    let modules = worker::spawn_fn(&label, || {
        client.search(&search.query)
    }, true)?;

    for module in &modules {
        println!("{} ({}) - {} downloads {}", module.canonical().green(),
                            module.latest.yellow(),
                            module.downloads.separated_string(),
                            (if module.featured { "[featured]" } else { "" }).cyan());
        println!("\t{}", module.description);
    }

    Ok(())
}