Skip to content

Commit

Permalink
Finish main refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Virviil authored and David-OConnor committed Dec 3, 2021
1 parent 7415710 commit 030d19e
Show file tree
Hide file tree
Showing 13 changed files with 286 additions and 211 deletions.
3 changes: 2 additions & 1 deletion src/actions/clear.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{fs, path::Path};

use crate::util::{self, abort};
use crate::util::{self, abort, success};

#[derive(Clone)]
enum ClearChoice {
Expand Down Expand Up @@ -62,4 +62,5 @@ pub fn clear(pyflow_path: &Path, cache_path: &Path, script_env_path: &Path) {
}
}
}
success("Cache is cleared")
}
2 changes: 2 additions & 0 deletions src/actions/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use crate::{

use util::deps::sync;

// TODO: Refactor this function
#[allow(clippy::too_many_arguments)]
pub fn install(
cfg_path: &Path,
cfg: &Config,
Expand Down
15 changes: 13 additions & 2 deletions src/actions/list.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
use std::path::Path;
use std::{path::Path, process};

use termcolor::Color;

use crate::{
dep_types::Req,
util::{self, print_color, print_color_},
pyproject,
util::{self, abort, print_color, print_color_},
};

/// List all installed dependencies and console scripts, by examining the `libs` and `bin` folders.
/// Also include path requirements, which won't appear in the `lib` folder.
pub fn list(lib_path: &Path, path_reqs: &[Req]) {
// This part check that project and venvs exists
let pcfg = pyproject::current::get_config().unwrap_or_else(|| process::exit(1));
let num_venvs = util::find_venvs(&pcfg.pypackages_path).len();

if !pcfg.config_path.exists() && num_venvs == 0 {
abort("Can't find a project in this directory")
} else if num_venvs == 0 {
abort("There's no python environment set up for this project")
}

let installed = util::find_installed(lib_path);
let scripts = find_console_scripts(&lib_path.join("../bin"));

Expand Down
11 changes: 6 additions & 5 deletions src/actions/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ mod install;
mod list;
mod new;
mod package;
mod reset;
mod run;
mod switch;

pub use clear::clear;
pub use init::init;
pub use install::install;
pub use list::list;
pub use new::new;
pub use package::package;

pub const NEW_ERROR_MESSAGE: &str = indoc::indoc! {r#"
Problem creating the project. This may be due to a permissions problem.
If on linux, please try again with `sudo`.
"#};
pub use reset::reset;
pub use run::run;
pub use switch::switch;
21 changes: 19 additions & 2 deletions src/actions/new.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use std::{

use termcolor::Color;

use crate::{commands, util, Config};
use crate::{
commands,
util::{self, abort, success},
Config,
};

const GITIGNORE_INIT: &str = indoc::indoc! {r##"
# General Python ignores
Expand All @@ -23,8 +27,21 @@ __pypackages__/
# Project ignores
"##};

pub const NEW_ERROR_MESSAGE: &str = indoc::indoc! {r#"
Problem creating the project. This may be due to a permissions problem.
If on linux, please try again with `sudo`.
"#};

pub fn new(name: &str) {
if new_internal(name).is_err() {
abort(NEW_ERROR_MESSAGE);
}
success(&format!("Created a new Python project named {}", name))
}

// TODO: Join this function after refactoring
/// Create a template directory for a python project.
pub fn new(name: &str) -> Result<(), Box<dyn Error>> {
fn new_internal(name: &str) -> Result<(), Box<dyn Error>> {
if !PathBuf::from(name).exists() {
fs::create_dir_all(&format!("{}/{}", name, name.replace("-", "_")))?;
fs::File::create(&format!("{}/{}/__init__.py", name, name.replace("-", "_")))?;
Expand Down
17 changes: 17 additions & 0 deletions src/actions/reset.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::{fs, process};

use crate::{
pyproject,
util::{abort, success},
};

pub fn reset() {
let pcfg = pyproject::current::get_config().unwrap_or_else(|| process::exit(1));
if (&pcfg.pypackages_path).exists() && fs::remove_dir_all(&pcfg.pypackages_path).is_err() {
abort("Problem removing `__pypackages__` directory")
}
if (&pcfg.lock_path).exists() && fs::remove_file(&pcfg.lock_path).is_err() {
abort("Problem removing `pyflow.lock`")
}
success("`__pypackages__` folder and `pyflow.lock` removed")
}
72 changes: 72 additions & 0 deletions src/actions/run.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use std::path::Path;

use regex::Regex;

use crate::{commands, pyproject::Config, util::abort};

/// Execute a python CLI tool, either specified in `pyproject.toml`, or in a dependency.
pub fn run(lib_path: &Path, bin_path: &Path, vers_path: &Path, cfg: &Config, args: Vec<String>) {
// Allow both `pyflow run ipython` (args), and `pyflow ipython` (opt.script)
if args.is_empty() {
return;
}

let name = if let Some(a) = args.get(0) {
a.clone()
} else {
abort("`run` must be followed by the script to run, eg `pyflow run black`");
};

// If the script we're calling is specified in `pyproject.toml`, ensure it exists.

// todo: Delete these scripts as required to sync with pyproject.toml.
let re = Regex::new(r"(.*?):(.*)").unwrap();

let mut specified_args: Vec<String> = args.into_iter().skip(1).collect();

// If a script name is specified by by this project and a dependency, favor
// this project.
if let Some(s) = cfg.scripts.get(&name) {
let abort_msg = format!(
"Problem running the function {}, specified in `pyproject.toml`",
name,
);

if let Some(caps) = re.captures(s) {
let module = caps.get(1).unwrap().as_str();
let function = caps.get(2).unwrap().as_str();
let mut args_to_pass = vec![
"-c".to_owned(),
format!(r#"import {}; {}.{}()"#, module, module, function),
];

args_to_pass.append(&mut specified_args);
if commands::run_python(bin_path, &[lib_path.to_owned()], &args_to_pass).is_err() {
abort(&abort_msg);
}
} else {
abort(&format!("Problem parsing the following script: {:#?}. Must be in the format module:function_name", s));
}
return;
}
// None => {
let abort_msg = format!(
"Problem running the CLI tool {}. Is it installed? \
Try running `pyflow install {}`",
name, name
);
let script_path = vers_path.join("bin").join(name);
if !script_path.exists() {
abort(&abort_msg);
}

let mut args_to_pass = vec![script_path
.to_str()
.expect("Can't find script path")
.to_owned()];

args_to_pass.append(&mut specified_args);
if commands::run_python(bin_path, &[lib_path.to_owned()], &args_to_pass).is_err() {
abort(&abort_msg);
}
}
19 changes: 19 additions & 0 deletions src/actions/switch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use std::{path::PathBuf, process};

use termcolor::Color;

use crate::{files, pyproject, util};

/// Updates `pyproject.toml` with a new python version
pub fn switch(version: &str) {
let mut pcfg = pyproject::current::get_config().unwrap_or_else(|| process::exit(1));

let specified = util::fallible_v_parse(version);
pcfg.config.py_version = Some(specified.clone());
files::change_py_vers(&PathBuf::from(&pcfg.config_path), &specified);
util::print_color(
&format!("Switched to Python version {}", specified.to_string()),
Color::Green,
);
// Don't exit program here; now that we've changed the cfg version, let's run the normal flow.
}
Loading

0 comments on commit 030d19e

Please sign in to comment.