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
162
163
164
165
166
167
//! CLI command structures, parsing, and execution.
#![allow(clippy::redundant_closure)]

pub mod build;
mod generate;
mod login;
mod pack;
/// Data structures and functions for publishing a package.
pub mod publish;
pub mod test;
pub mod utils;

use self::build::{Build, BuildOptions};
use self::generate::generate;
use self::login::login;
use self::pack::pack;
use self::publish::{access::Access, publish};
use self::test::{Test, TestOptions};
use crate::install::InstallMode;
use failure::Error;
use log::info;
use std::path::PathBuf;
use std::result;

/// The various kinds of commands that `wasm-pack` can execute.
#[derive(Debug, StructOpt)]
pub enum Command {
    /// πŸ—οΈ  build your npm package!
    #[structopt(name = "build", alias = "init")]
    Build(BuildOptions),

    #[structopt(name = "pack")]
    /// 🍱  create a tar of your npm package but don't publish!
    Pack {
        /// The path to the Rust crate. If not set, searches up the path from the current dirctory.
        #[structopt(parse(from_os_str))]
        path: Option<PathBuf>,
    },

    #[structopt(name = "new")]
    /// πŸ‘ create a new project with a template
    Generate {
        /// The name of the project
        name: String,
        /// The URL to the template
        #[structopt(
            long = "template",
            short = "temp",
            default_value = "https://github.com/rustwasm/wasm-pack-template"
        )]
        template: String,
        #[structopt(long = "mode", short = "m", default_value = "normal")]
        /// Should we install or check the presence of binary tools. [possible values: no-install, normal, force]
        mode: InstallMode,
    },

    #[structopt(name = "publish")]
    /// πŸŽ†  pack up your npm package and publish!
    Publish {
        #[structopt(long = "target", short = "t", default_value = "bundler")]
        /// Sets the target environment. [possible values: bundler, nodejs, web, no-modules]
        target: String,

        /// The access level for the package to be published
        #[structopt(long = "access", short = "a")]
        access: Option<Access>,

        /// The distribution tag being used for publishing.
        /// See https://docs.npmjs.com/cli/dist-tag
        #[structopt(long = "tag")]
        tag: Option<String>,

        /// The path to the Rust crate. If not set, searches up the path from the current dirctory.
        #[structopt(parse(from_os_str))]
        path: Option<PathBuf>,
    },

    #[structopt(name = "login", alias = "adduser", alias = "add-user")]
    /// πŸ‘€  Add an npm registry user account! (aliases: adduser, add-user)
    Login {
        #[structopt(long = "registry", short = "r")]
        /// Default: 'https://registry.npmjs.org/'.
        /// The base URL of the npm package registry. If scope is also
        /// specified, this registry will only be used for packages with that
        /// scope. scope defaults to the scope of the project directory you're
        /// currently in, if any.
        registry: Option<String>,

        #[structopt(long = "scope", short = "s")]
        /// Default: none.
        /// If specified, the user and login credentials given will be
        /// associated with the specified scope.
        scope: Option<String>,

        #[structopt(long = "always-auth", short = "a")]
        /// If specified, save configuration indicating that all requests to the
        /// given registry should include authorization information. Useful for
        /// private registries. Can be used with --registry and / or --scope
        always_auth: bool,

        #[structopt(long = "auth-type", short = "t")]
        /// Default: 'legacy'.
        /// Type: 'legacy', 'sso', 'saml', 'oauth'.
        /// What authentication strategy to use with adduser/login. Some npm
        /// registries (for example, npmE) might support alternative auth
        /// strategies besides classic username/password entry in legacy npm.
        auth_type: Option<String>,
    },

    #[structopt(name = "test")]
    /// πŸ‘©β€πŸ”¬  test your wasm!
    Test(TestOptions),
}

/// Run a command with the given logger!
pub fn run_wasm_pack(command: Command) -> result::Result<(), Error> {
    // Run the correct command based off input and store the result of it so that we can clear
    // the progress bar then return it
    match command {
        Command::Build(build_opts) => {
            info!("Running build command...");
            Build::try_from_opts(build_opts).and_then(|mut b| b.run())
        }
        Command::Pack { path } => {
            info!("Running pack command...");
            info!("Path: {:?}", &path);
            pack(path)
        }
        Command::Generate {
            template,
            name,
            mode,
        } => {
            info!("Running generate command...");
            info!("Template: {:?}", &template);
            info!("Name: {:?}", &name);
            generate(template, name, mode.install_permitted())
        }
        Command::Publish {
            target,
            path,
            access,
            tag,
        } => {
            info!("Running publish command...");
            info!("Path: {:?}", &path);
            publish(&target, path, access, tag)
        }
        Command::Login {
            registry,
            scope,
            always_auth,
            auth_type,
        } => {
            info!("Running login command...");
            info!(
                "Registry: {:?}, Scope: {:?}, Always Auth: {}, Auth Type: {:?}",
                &registry, &scope, &always_auth, &auth_type
            );
            login(registry, &scope, always_auth, &auth_type)
        }
        Command::Test(test_opts) => {
            info!("Running test command...");
            Test::try_from_opts(test_opts).and_then(|t| t.run())
        }
    }
}