Move login to clap
authorAleksey Kladov <aleksey.kladov@gmail.com>
Wed, 7 Mar 2018 13:17:10 +0000 (16:17 +0300)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 8 Mar 2018 20:30:46 +0000 (23:30 +0300)
src/bin/cargo.rs
src/bin/cli/login.rs [new file with mode: 0644]
src/bin/cli/mod.rs

index 7b34fecee045a416d993c3ea5604c32b46910f23..6e0b367003757366962c9f1f43d0a1176b34453e 100644 (file)
@@ -90,7 +90,7 @@ fn main() {
 
     let is_clapified = ::std::env::args().any(|arg| match arg.as_ref() {
         "build" | "bench" | "check" | "clean" | "doc" | "fetch" | "generate-lockfile" | "git-checkout" |
-        "init" | "install" | "locate-project" => true,
+        "init" | "install" | "locate-project" | "login" => true,
         _ => false
     });
 
@@ -130,7 +130,7 @@ macro_rules! each_subcommand{
 //        $mac!(init);
 //        $mac!(install);
 //        $mac!(locate_project);
-        $mac!(login);
+//        $mac!(login);
         $mac!(metadata);
         $mac!(new);
         $mac!(owner);
diff --git a/src/bin/cli/login.rs b/src/bin/cli/login.rs
new file mode 100644 (file)
index 0000000..957bfe1
--- /dev/null
@@ -0,0 +1,10 @@
+use super::utils::*;
+
+pub fn cli() -> App {
+    subcommand("login")
+        .about("Save an api token from the registry locally. \
+                If token is not specified, it will be read from stdin.")
+        .arg(Arg::with_name("token"))
+        .arg(opt("host", "Host to set the token for").value_name("HOST"))
+        .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
+}
index 755f53077ba2583063385898ab1356cb5bf7956f..cded0f3996a25d8684186877b3ab93e69766bfc7 100644 (file)
@@ -3,17 +3,19 @@ extern crate clap;
 extern crate cargo;
 
 use std::slice;
-
-use cargo;
+use std::io::{self, BufRead};
+use std::path::PathBuf;
 
 use clap::{AppSettings, Arg, ArgMatches};
-use cargo::{Config, CargoResult, CliError};
+
+use cargo::{self, Config, CargoResult, CargoError, CliError};
 use cargo::core::{Workspace, Source, SourceId, GitReference};
-use cargo::util::ToUrl;
+use cargo::util::{ToUrl, CargoResultExt};
 use cargo::util::important_paths::find_root_manifest_for_wd;
 use cargo::ops::{self, MessageFormat, Packages, CompileOptions, CompileMode, VersionControl};
-use cargo::sources::GitSource;
+use cargo::sources::{GitSource, RegistrySource};
 
+use self::utils::*;
 
 pub fn do_main(config: &mut Config) -> Result<(), CliError> {
     let args = cli().get_matches();
@@ -282,12 +284,47 @@ pub fn do_main(config: &mut Config) -> Result<(), CliError> {
             cargo::print_json(&location);
             return Ok(());
         }
+        ("login", Some(args)) => {
+            let registry = args.value_of("registry").map(|s| s.to_string());
+            if registry.is_some() && !config.cli_unstable().unstable_options {
+                return Err(format_err!("registry option is an unstable feature and \
+                                requires -Zunstable-options to use.").into());
+            }
+
+            let token = match args.value_of("token") {
+                Some(token) => token.to_string(),
+                None => {
+                    let host = match registry {
+                        Some(ref _registry) => {
+                            return Err(format_err!("token must be provided when \
+                                            --registry is provided.").into())
+                        }
+                        None => {
+                            let src = SourceId::crates_io(config)?;
+                            let mut src = RegistrySource::remote(&src, config);
+                            src.update()?;
+                            let config = src.config()?.unwrap();
+                            args.value_of("host").map(|s| s.to_string())
+                                .unwrap_or(config.api.unwrap())
+                        }
+                    };
+                    println!("please visit {}me and paste the API Token below", host);
+                    let mut line = String::new();
+                    let input = io::stdin();
+                    input.lock().read_line(&mut line).chain_err(|| {
+                        "failed to read stdin"
+                    }).map_err(CargoError::from)?;
+                    line.trim().to_string()
+                }
+            };
+
+            ops::registry_login(config, token, registry)?;
+            return Ok(());
+        }
         _ => return Ok(())
     }
 }
 
-use self::utils::*;
-use std::path::PathBuf;
 
 fn cli() -> App {
     let app = App::new("cargo")
@@ -364,6 +401,7 @@ See 'cargo help <command>' for more information on a specific command.
             init::cli(),
             install::cli(),
             locate_project::cli(),
+            login::cli(),
         ])
     ;
     app
@@ -383,6 +421,7 @@ mod git_checkout;
 mod init;
 mod install;
 mod locate_project;
+mod login;
 
 mod utils {
     use clap::{self, SubCommand, AppSettings};