Skip to content

Commit

Permalink
Fixed a bug with uninstalling packages that use nonstandard names
Browse files Browse the repository at this point in the history
  • Loading branch information
David-OConnor committed Oct 5, 2019
1 parent 523f0ce commit f34bd71
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 23 deletions.
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
- Fixed a bug with uninstalling packages that use non-standard naming conventions
- Fixed a bug with installing on Mac
- Fixed a bug uninstalling packages from the CLI
- Added support for adding dependencies from git repos

## v0.1.4
- Clear now lets the user choose which parts of the cache to clear
Expand Down
11 changes: 6 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ This tool manages Python installations and dependencies.

![Demonstration](https://raw.githubusercontent.com/david-oconnor/pyflow/master/demo.gif)

**Goals**: Make using and publishing Python projects as simple as possible. Understanding
Python environments shouldn't be required to use dependencies safely. We're attempting
**Goals**: Make using and publishing Python projects as simple as possible. Actively
managing Python environments shouldn't be required to use dependencies safely. We're attempting
to fix each stumbling block in the Python workflow, so that it's as elegant
as the language itself.

Expand All @@ -32,11 +32,11 @@ and [Pep 518 (pyproject.toml)](https://www.python.org/dev/peps/pep-0518/), and s
- **Ubuntu, or Debian:** - Download and run
[this deb](https://github.com/David-OConnor/pyflow/releases/download/0.1.4/pyflow_0.1.4_amd64.deb).

- **A different Linux distro:** - Download this [standalone binary](https://github.com/David-OConnor/pyflow/releases/download/0.1.4/pyflow)
- **A different Linux distro** - Download this [standalone binary](https://github.com/David-OConnor/pyflow/releases/download/0.1.4/pyflow)
and place it somewhere
accessible by the PATH. For example, `/usr/bin`.

- **Mac:** - Build from source using the instructions near the bottom of this page,
- **Mac** - Build from source using the instructions near the bottom of this page,
or install via `cargo`. (If able, please PR the binary.)

- **If you have [Rust](https://www.rust-lang.org) installed** - Run `cargo install pyflow`.
Expand Down Expand Up @@ -252,7 +252,8 @@ entry points for somone using the package, regardless of if they're using this t
If an environment isn't already set up for the version specified in `pyproject.toml`, sets one up. If
no version is specified, it asks you.
- `pyflow install requests` - If you specify one or more packages after `install`, those packages will
be added to `pyproject.toml` and installed
be added to `pyproject.toml` and installed. You can use the `--dev` flag to install dev dependencies. eg:
`pyflow install black --dev`.
- `pyflow install numpy==1.16.4 matplotlib>=3.1` - Example with multiple dependencies, and specified versions
- `pyflow uninstall requests` - Remove one or more dependencies

Expand Down
9 changes: 2 additions & 7 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::util;
use crossterm::Color;
use regex::Regex;
//use std::process::Stdio;
use std::{error::Error, fmt};
Expand Down Expand Up @@ -122,13 +121,9 @@ pub fn download_git_repo(repo: &str, lib_path: &Path) -> Result<(), Box<dyn Erro

/// Initialize a new git repo.
pub fn git_init(dir: &Path) -> Result<(), Box<dyn Error>> {
if Command::new("git")
Command::new("git")
.current_dir(dir)
.args(&["init", "--quiet"])
.status()
.is_err()
{
util::print_color("Unable to initialize a git repo", Color::DarkRed);
}
.status()?;
Ok(())
}
4 changes: 2 additions & 2 deletions src/dep_resolution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,11 +438,11 @@ fn make_renamed_packs(
util::print_color(
&format!(
"Installing multiple versions for {}. If this package uses \
compiled code or importlib, this may fail when importing. Note that \
compiled code or importlib, this may fail when importing. Note that \
your package may not be published unless this is resolved...",
name
),
Color::DarkRed,
Color::DarkYellow,
);

let dep_display: Vec<String> = deps
Expand Down
1 change: 0 additions & 1 deletion src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,6 @@ pub struct Pyflow {
pub name: Option<String>,
pub version: Option<String>,
pub authors: Option<Vec<String>>,
// pub author_email: Option<String>,
pub license: Option<String>,
pub description: Option<String>,
pub classifiers: Option<Vec<String>>, // https://pypi.org/classifiers/
Expand Down
34 changes: 29 additions & 5 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ pub struct Config {
dev_reqs: Vec<Req>,
version: Option<Version>,
authors: Vec<String>,
// author_email: Option<String>,
license: Option<String>,
extras: HashMap<String, String>,
description: Option<String>,
Expand Down Expand Up @@ -504,7 +503,10 @@ __pypackages__/
cfg.write_file(&format!("{}/pyproject.toml", name));

if commands::git_init(Path::new(name)).is_err() {
abort("Problem creating a git repo for your project");
util::print_color(
"Unable to initialize a git repo for your project",
Color::DarkYellow,
);
};

Ok(())
Expand Down Expand Up @@ -572,7 +574,17 @@ fn sync_deps(
// Filter by not-already-installed.
let to_install: Vec<&PackToInstall> = packages
.iter()
.filter(|(pack, _)| !installed.contains(pack))
.filter(|(pack, _)| {
let mut contains = false;
for inst in &installed {
if util::compare_names(&pack.0, &inst.0) && pack.1 == inst.1 {
contains = true;
break;
}
}

!contains
})
.collect();

// todo: Once you include rename info in installed, you won't need to use the map logic here.
Expand All @@ -583,7 +595,15 @@ fn sync_deps(
// Don't standardize the name here; we need original capitalization to uninstall
// metadata etc.
let inst = (inst.0.clone(), inst.1);
!packages_only.contains(&&inst)
let mut contains = false;
// We can't just use the contains method, due to needing compare_names().
for pack in &packages_only {
if util::compare_names(&pack.0, &inst.0) && pack.1 == inst.1 {
contains = true;
break;
}
}
!contains
})
.collect();

Expand Down Expand Up @@ -649,7 +669,11 @@ fn sync_deps(
for ((name, version), rename) in &to_install {
if let Some((id, new)) = rename {
// Rename in the renamed package
install::rename_package_files(&lib_path.join(util::standardize_name(new)), name, new);

let renamed_path = &lib_path.join(util::standardize_name(new));

util::wait_for_dirs(&[renamed_path.clone()]).expect("Problem creating renamed path");
install::rename_package_files(renamed_path, name, new);

// Rename in the parent calling the renamed package. // todo: Multiple parents?
let parent = lock_packs
Expand Down
3 changes: 1 addition & 2 deletions src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ use crate::{
use crossterm::{Color, Colored};
use regex::Regex;
use serde::Deserialize;
use std::env::home_dir;
use std::io::{self, BufRead, BufReader, Read};
use std::str::FromStr;
use std::{
Expand Down Expand Up @@ -349,7 +348,7 @@ pub fn merge_reqs(
}

pub fn standardize_name(name: &str) -> String {
name.to_lowercase().replace('-', "_")
name.to_lowercase().replace('-', "_").replace('.', "_")
}

// PyPi naming isn't consistent; it capitalization and _ vs -
Expand Down

0 comments on commit f34bd71

Please sign in to comment.