From 088ea8af12601f3e0559295680e626724a11a7e5 Mon Sep 17 00:00:00 2001 From: Noah <33094578+coolreader18@users.noreply.github.com> Date: Wed, 14 Apr 2021 15:16:45 -0500 Subject: [PATCH] Add --install-pip cli option, tidy up src/lib.rs --- src/lib.rs | 81 +++++++++++++++++++++++++++++++++----------------- vm/src/lib.rs | 1 - vm/src/util.rs | 13 -------- 3 files changed, 53 insertions(+), 42 deletions(-) delete mode 100644 vm/src/util.rs diff --git a/src/lib.rs b/src/lib.rs index 7a48625d2..904c43e7f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -52,7 +52,7 @@ use rustpython_vm::{ match_class, pyobject::{BorrowValue, ItemProtocol, PyResult, TypeProtocol}, scope::Scope, - sysmodule, util, InitParameter, Interpreter, PySettings, VirtualMachine, + sysmodule, InitParameter, Interpreter, PySettings, VirtualMachine, }; use std::convert::TryInto; @@ -121,18 +121,18 @@ where Ok(()) => 0, Err(err) if err.isinstance(&vm.ctx.exceptions.system_exit) => { let args = err.args(); - match args.borrow_value().len() { - 0 => 0, - 1 => match_class!(match args.borrow_value()[0].clone() { - i @ PyInt => { + match args.borrow_value() { + [] => 0, + [arg] => match_class!(match arg { + ref i @ PyInt => { use num_traits::cast::ToPrimitive; i.borrow_value().to_i32().unwrap_or(0) } arg => { - if vm.is_none(&arg) { + if vm.is_none(arg) { 0 } else { - if let Ok(s) = vm.to_str(&arg) { + if let Ok(s) = vm.to_str(arg) { eprintln!("{}", s); } 1 @@ -207,6 +207,16 @@ fn parse_arguments<'a>(app: App<'a, '_>) -> ArgMatches<'a> { .min_values(1) .help("run library module as script"), ) + .arg( + Arg::with_name("install_pip") + .long("install-pip") + .takes_value(true) + .allow_hyphen_values(true) + .multiple(true) + .value_name("get-pip args") + .min_values(0) + .help("install the pip package manager for rustpython"), + ) .arg( Arg::with_name("optimize") .short("O") @@ -414,6 +424,10 @@ fn create_settings(matches: &ArgMatches) -> PySettings { std::iter::once("PLACEHOLDER".to_owned()) .chain(module.skip(1).map(ToOwned::to_owned)) .collect() + } else if let Some(get_pip_args) = matches.values_of("install_pip") { + std::iter::once("get-pip.py".to_owned()) + .chain(get_pip_args.map(ToOwned::to_owned)) + .collect() } else if let Some(cmd) = matches.values_of("c") { std::iter::once("-c".to_owned()) .chain(cmd.skip(1).map(ToOwned::to_owned)) @@ -530,6 +544,27 @@ fn run_rustpython(vm: &VirtualMachine, matches: &ArgMatches) -> PyResult<()> { run_command(&vm, scope, command.to_owned())?; } else if let Some(module) = matches.value_of("m") { run_module(&vm, module)?; + } else if matches.is_present("install_pip") { + let get_getpip = rustpython_vm::py_compile!( + source = r#"\ +__import__("io").TextIOWrapper( + __import__("urllib.request").request.urlopen("https://bootstrap.pypa.io/get-pip.py") +).read() +"#, + mode = "eval" + ); + eprintln!("downloading get-pip.py..."); + let getpip_code = vm.run_code_obj(vm.new_code_object(get_getpip), scope.clone())?; + let getpip_code: rustpython_vm::builtins::PyStrRef = getpip_code + .downcast() + .expect("TextIOWrapper.read() should return str"); + eprintln!("running get-pip.py..."); + _run_string( + vm, + scope, + getpip_code.borrow_value(), + "get-pip.py".to_owned(), + )?; } else if let Some(filename) = matches.value_of("script") { run_script(&vm, scope.clone(), filename)?; if matches.is_present("inspect") { @@ -573,34 +608,24 @@ fn run_module(vm: &VirtualMachine, module: &str) -> PyResult<()> { fn run_script(vm: &VirtualMachine, scope: Scope, script_file: &str) -> PyResult<()> { debug!("Running file {}", script_file); - // Parse an ast from it: - let file_path = PathBuf::from(script_file); - let file_path = if file_path.is_file() { - file_path - } else if file_path.is_dir() { - let main_file_path = file_path.join("__main__.py"); - if main_file_path.is_file() { - main_file_path - } else { - error!( - "can't find '__main__' module in '{}'", - file_path.to_str().unwrap() - ); + let mut file_path = PathBuf::from(script_file); + let file_meta = file_path.metadata().unwrap_or_else(|e| { + error!("can't open file '{}': {}", file_path.display(), e); + process::exit(1); + }); + if file_meta.is_dir() { + file_path.push("__main__.py"); + if !file_path.is_file() { + error!("can't find '__main__' module in '{}'", file_path.display()); process::exit(1); } - } else { - error!( - "can't open file '{}': No such file or directory", - file_path.to_str().unwrap() - ); - process::exit(1); - }; + } let dir = file_path.parent().unwrap().to_str().unwrap().to_owned(); let sys_path = vm.get_attribute(vm.sys_module.clone(), "path").unwrap(); vm.call_method(&sys_path, "insert", (0, dir))?; - match util::read_file(&file_path) { + match std::fs::read_to_string(&file_path) { Ok(source) => { _run_string(vm, scope, &source, file_path.to_str().unwrap().to_owned())?; } diff --git a/vm/src/lib.rs b/vm/src/lib.rs index eb53518da..6039d9ba2 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -70,7 +70,6 @@ pub mod slots; pub mod stdlib; pub mod sysmodule; pub mod types; -pub mod util; mod version; mod vm; diff --git a/vm/src/util.rs b/vm/src/util.rs deleted file mode 100644 index a5217a37e..000000000 --- a/vm/src/util.rs +++ /dev/null @@ -1,13 +0,0 @@ -use std::fs::File; -use std::io::{Read, Result}; -use std::path::Path; - -/// Read a file at `path` into a String -pub fn read_file(path: &Path) -> Result { - info!("Loading file {:?}", path); - let mut f = File::open(&path)?; - let mut buffer = String::new(); - f.read_to_string(&mut buffer)?; - - Ok(buffer) -}