Skip to content

Commit

Permalink
Release
Browse files Browse the repository at this point in the history
  • Loading branch information
David-OConnor committed Sep 27, 2019
1 parent 8b1f634 commit 5ef33f7
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 27 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

## v0.1.2
- Added support for installing Python on most Linux distros
- Fixed a bug related to creating `pyflow` directory
- Fixed a bug in specifying package url with the `publish` command.
- Wheel is now installed directly, instead of with Pip; should only be dependent on
pip now to install `twine`.
- Now doesn't ask to choose between aliases pointing to the same Python install.
- Fixed a bug related to creating `pyflow` directory
- Fixed a bug in specifying package url with the `publish` command.


## v0.1.1
- Fixed a bug, where spaces could prevent console scripts from being installed
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ as the language itself.
You don't need Python or any other tools installed to use Pyflow.

It can run standalone scripts in their
own environments with no config, and project functions directly from the CLI.
own environments with no config, and functions directly from the CLI.

It implements [PEP 582 -- Python local packages directory](https://www.python.org/dev/peps/pep-0582/)
and [Pep 518 (pyproject.toml)](https://www.python.org/dev/peps/pep-0518/), and supports Python ≥ 3.4.
Expand Down Expand Up @@ -61,7 +61,7 @@ to run one-off Python files that aren't attached to a project, but have dependen
Some reasons why this is different:

- It automatically manages Python installations and environments. You specify a Python version
in `pyproject.toml` (if ommitted, itasks), and ensures that version is used.
in `pyproject.toml` (if ommitted, it asks), and ensures that version is used.
If the version's not installed, Pyflow downloads a binary, and uses that.
If multiple installations are found for that version, it asks which to use.

Expand Down Expand Up @@ -89,9 +89,9 @@ of conflicting sub-dependencies. (ie: Your package requires `Dep A>=1.0` and `De
`Dep B` requires Dep `A==0.9`) There are many cases where `Poetry` and `Pipenv` will fail
to resolve dependencies. Try it for yourself with a few
random dependencies from [pypi](https://pypi.org/); there's a good chance you'll
hit this problem using `Poetry` or `Pipenv`. Limitations: This will not work for
hit this problem using `Poetry` or `Pipenv`. *Limitations: This will not work for
some compiled dependencies, and attempting to package something using this will
trigger an error.
trigger an error.*


## My OS comes with Python, and Virtual environments are easy. What's the point of this?
Expand Down Expand Up @@ -132,7 +132,7 @@ These tools have different scopes and purposes:
|------|------------|--------|--------|-------|-----------|-------|-----|
| **Manages dependencies** |||| | |||
| **Manages Python installations** | | | || |||
|| **Py-environment-agnostic** | | | || |||
| **Py-environment-agnostic** | | | || |||
| **Included with Python** || | | | | | |
| **Stores packages with project** | | | | || ||
| **Locks dependencies** | ||| | |||
Expand Down
27 changes: 25 additions & 2 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,29 @@ impl fmt::Display for _ExecutionError {
}
}

/// Todo: Dry from find_py_version
pub fn find_py_dets(alias: &str) -> Option<String> {
let output = Command::new(alias).args(&["--version, --version"]).output();

let output_bytes = match output {
Ok(ob) => {
// Old versions of python output `--version` to `stderr`; newer ones to `stdout`,
// so check both.
if ob.stdout.is_empty() {
ob.stderr
} else {
ob.stdout
}
}
Err(_) => return None,
};

match std::str::from_utf8(&output_bytes) {
Ok(r) => Some(r.to_owned()),
Err(_) => None,
}
}

/// Find the py_version from the `python --py_version` command. Eg: "Python 3.7".
pub fn find_py_version(alias: &str) -> Option<crate::Version> {
let output = Command::new(alias).arg("--version").output();
Expand Down Expand Up @@ -61,7 +84,7 @@ pub(crate) fn create_venv(
lib_path: &Path,
name: &str,
) -> Result<(), Box<dyn Error>> {
// While creating the lib path, we're creating the __pypackages__ structure.
// While creating the lib path, we're creating the __pypackages__ structure.
Command::new(py_alias)
.args(&["-m", "venv", name])
.current_dir(lib_path.join("../"))
Expand All @@ -76,7 +99,7 @@ pub(crate) fn create_venv2(
lib_path: &Path,
name: &str,
) -> Result<(), Box<dyn Error>> {
// While creating the lib path, we're creating the __pypackages__ structure.
// While creating the lib path, we're creating the __pypackages__ structure.
Command::new(py_alias)
.args(&["-m", "venv", name])
.current_dir(lib_path.join("../"))
Expand Down
9 changes: 7 additions & 2 deletions src/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pub struct Poetry {
// pub extras: Option<HashMap<String, String>>,
}

/// Write dependencies to pyproject.toml. If an entry for tha = true;t package already exists, ask if
/// Write dependencies to pyproject.toml. If an entry for that package already exists, ask if
/// we should update the version. Assume we've already parsed the config, and are only
/// adding new reqs, or ones with a changed version.
pub fn add_reqs_to_cfg(filename: &str, added: &[Req]) {
Expand All @@ -131,7 +131,12 @@ pub fn add_reqs_to_cfg(filename: &str, added: &[Req]) {
result.push_str("\n");
if line == "[tool.pyflow.dependencies]" {
in_dep = true;
continue;

if i != lines_vec.len() - 1 {
// If the last line's the start of dependencies section, don't move on;
// we'll add now.
continue;
}
}

if in_dep {
Expand Down
36 changes: 23 additions & 13 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ impl Config {
for dep in self.reqs.iter() {
result.push_str(&(dep.to_cfg_string() + "\n"));
}
result.push_str("\n"); // trailing newline

match fs::write(file, result) {
Ok(_) => util::print_color("Created `pyproject.toml`", Color::Green),
Expand Down Expand Up @@ -499,7 +500,6 @@ package_url = "https://test.pypi.org/legacy/"
[tool.pyflow.dependencies]
"##,
name
);
Expand Down Expand Up @@ -720,21 +720,33 @@ fn sync_deps(
let (best_release, package_type) =
find_best_release(&data, &name, &version, os, python_vers);

// Powershell doesn't like emojis // todo format literal issues
// #[cfg(target_os = "windows")]
// let text = "Installing {}{}{} {} ...";
// #[cfg(target_os = "linux")]
// let text = "⬇️ Installing {}{}{} {} ...";
// #[cfg(target_os = "macos")]
// let text = "⬇️ Installing {}{}{} {} ...";

// Powershell doesn't like emojis
// todo format literal issues, so repeating this whole statement.
#[cfg(target_os = "windows")]
println!(
"Installing {}{}{} {} ...",
Colored::Fg(Color::Cyan),
&name,
Colored::Fg(Color::Reset),
&version
);
#[cfg(target_os = "linux")]
println!(
"⬇️ Installing {}{}{} {} ...",
Colored::Fg(Color::Cyan),
&name,
Colored::Fg(Color::Reset),
&version
);
#[cfg(target_os = "macos")]
println!(
"⬇️ Installing {}{}{} {} ...",
Colored::Fg(Color::Cyan),
&name,
Colored::Fg(Color::Reset),
&version
);

if install::download_and_install_package(
&name,
&version,
Expand Down Expand Up @@ -826,9 +838,8 @@ fn run_cli_tool(
// If a script name is specified by by this project and a dependency, favor
// this project.
if let Some(s) = cfg.scripts.get(&name) {
// Some(s) => {
let abort_msg = format!(
"Problem running the script {}, specified in `pyproject.toml`",
"Problem running the function {}, specified in `pyproject.toml`",
name,
);

Expand All @@ -855,7 +866,7 @@ fn run_cli_tool(
}
// None => {
let abort_msg = format!(
"Problem running the script {}. Is it installed? \
"Problem running the CLI tool {}. Is it installed? \
Try running `pyflow install {}`",
name, name
);
Expand Down Expand Up @@ -1147,7 +1158,6 @@ fn sync(
// Now that we've confirmed or modified the lock file, we're ready to sync installed
// depenencies with it.
sync_deps(
// &bin_path, &lib_path, &packages, &installed, &os, &py_vers, &resolved,
&bin_path,
&lib_path,
&cache_path,
Expand Down
11 changes: 8 additions & 3 deletions src/py_versions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,13 +273,16 @@ pub fn find_py_aliases(version: &Version) -> Vec<(String, Version)> {
];

let mut result = Vec::new();
let mut found_dets = Vec::new();

for alias in possible_aliases {
// We use the --version command as a quick+effective way to determine if
// this command is associated with Python.
let dets = commands::find_py_dets(alias);
if let Some(v) = commands::find_py_version(alias) {
if v.major == version.major && v.minor == version.minor {
if v.major == version.major && v.minor == version.minor && !found_dets.contains(&dets) {
result.push((alias.to_string(), v));
found_dets.push(dets);
}
}
}
Expand Down Expand Up @@ -451,9 +454,11 @@ pub fn create_venv(
#[cfg(target_os = "windows")]
let venv_lib_path = "Lib";
#[cfg(target_os = "linux")]
let venv_lib_path = PathBuf::from("lib64").join(&format!("python{}.{}", py_ver.major, py_ver.minor));
let venv_lib_path =
PathBuf::from("lib64").join(&format!("python{}.{}", py_ver.major, py_ver.minor));
#[cfg(target_os = "macos")]
let venv_lib_path = PathBuf::from("lib64").join(&format!("python{}.{}", py_ver.major, py_ver.minor));
let venv_lib_path =
PathBuf::from("lib64").join(&format!("python{}.{}", py_ver.major, py_ver.minor));

install::download_and_install_package(
"wheel",
Expand Down

0 comments on commit 5ef33f7

Please sign in to comment.