Skip to content

Commit

Permalink
Release 0.1.1
Browse files Browse the repository at this point in the history
  • Loading branch information
MaximeLeMagicien committed Aug 8, 2024
1 parent 74526a3 commit 100b46a
Show file tree
Hide file tree
Showing 10 changed files with 65 additions and 43 deletions.
Binary file modified .DS_Store
Binary file not shown.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
env
dist
old
13 changes: 13 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# universalPip's changelog

## Version 0.1.0 and 0.1.1
Release date : 2024/08/08<br>

First package version.

<b>Statistics</b>
- Package size: 10 ko
- Number of files: 3
- Available distributions: `py3-none-any.whl` and `tar.gz`
- Available functions in the CLI: 8
- Compatible Python versions: `>=3.8`
82 changes: 44 additions & 38 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,37 @@
# README

## upip
## universalPip
#### Universal Package Installer for Python

[![PyPI](https://img.shields.io/pypi/v/universalPip)](https://pypi.org/project/universalPip/)
[![downloads](https://static.pepy.tech/badge/universalPip/month)](https://pepy.tech/project/universalPip)

## Table of contents
- [Description](#description)
- [Story](#story)
- [Note about universal wheels](#note-about-universal-wheels)
- [Note about packaging](#important-note-about-packaging)
- [`upip`'s installation logic](#upips-installation-logic)
- [Uninstall packages](#how-to-uninstall-packages-installed-by-upip)
- [`uPip`'s installation logic](#uPips-installation-logic)
- [Uninstall packages](#how-to-uninstall-packages-installed-by-uPip)
- [Install the CLI](#installation)
- [Usage](#usage)
- [Install a package](#install-a-package)
- [Create `universal2` wheel](#create-an-universal2-wheel)
- [Check if a package is universal](#check-if-a-package-is-universal)
- [Show default stored wheel directory](#show-default-stored-wheel-directory)
- [Invoke pip](#invoke-pip)
- [`upip`'s version](#printing-upips-version)
- [`uPip`'s version](#printing-uPips-version)
- [Print documentation](#print-documentation)
- [Contributing](#contributing)
- [License](#license)

## Changelog
You can view the complete changelog [here](https://github.com/MaximeLeMagicien/uPip/blob/main/Changelog.md).

<hr>

### Description
The `upip` package is a Python package which completes the `pip` command line tool provided with any standard Python3 installation. `upip`'s main goal is to provide an easy way to install any python package in `universal2` binary mode, which is compatible with any macOS installation.
The `universalPip` package (called `uPip` in this document) is a Python package which completes the `pip` command line tool provided with any standard Python3 installation. `uPip`'s main goal is to provide an easy way to install any python package in `universal2` binary mode, which is compatible with any macOS installation.

### Story
As you probably know, Apple recently stopped using `intel chips` as their processor for new macs. They released in September 2020 their own chip called the `M1`. Unfortunatly, apps built on intel chips can't run properly on M1 and newer chips. A complete app rebuild is necessary. Even if `rosetta` exists and enables the aibility to run `x86_64` apps on `M1` architecture, it is not a durable solution.
Expand All @@ -36,121 +42,121 @@ Those changes had an huge impact on Python packages. In fact, all binary files (

In order to compile applications in universal mode, with `pyinstaller` for example; installed wheels in the Python environment need to have both architectures inside their `.so` binaries files. Usually these wheel distributions are named like this: `macosx_11_0_universal2.whl` (See [here](#note-about-universal-wheels) for more information about compiling `universal2` applications using `pyinstaller`). <u>Unfortunatly, some packages do not provide these kind of wheels but only seperarated wheels for each architecture.</u>

`upip`'s story starts here: knowing all the facts mentionned above, the Python Package Index needed a new package to easily install any Python package in `universal2` mode. <u>`upip` has `pip`'s same capabilities but adds a layer of verification when installing a package. If no `universal2` distribution wheel exists in the package repository, it will download each architecture wheel and fusionnate their wheels to create an `universal2` distribution and then install it.</u> Read [installation logic](#upips-installation-logic) for further information.
`uPip`'s story starts here: knowing all the facts mentionned above, the Python Package Index needed a new package to easily install any Python package in `universal2` mode. <u>`uPip` has `pip`'s same capabilities but adds a layer of verification when installing a package. If no `universal2` distribution wheel exists in the package repository, it will download each architecture wheel and fusionnate their wheels to create an `universal2` distribution and then install it.</u> Read [installation logic](#uPips-installation-logic) for further information.

### Note about universal wheels
`upip`'s main goal is to handle the case where no `universal2` wheel distribution is provided for a package release. But not all packages needs an `universal2` wheel. In fact, if a package (like this one) doesn't have any binary dependencies, it often has only one release named `py3-none-any.whl` which means that all package's logic is coded in Python only and is compatible with any installation. So, even on `arm64` or `x86_64` mac architectures, those packages will work normally. See [installation logic](#upips-installation-logic) for more information.
`uPip`'s main goal is to handle the case where no `universal2` wheel distribution is provided for a package release. But not all packages needs an `universal2` wheel. In fact, if a package (like this one) doesn't have any binary dependencies, it often has only one release named `py3-none-any.whl` which means that all package's logic is coded in Python only and is compatible with any installation. So, even on `arm64` or `x86_64` mac architectures, those packages will work normally. See [installation logic](#uPips-installation-logic) for more information.

### Important note about packaging
Even if compiling universal app bundles for both `x86_64` and `arm64` architectures is possible, universal applications are way heavier in terms of size than separated architecture applications. For instance, a small app packaged with `pyinstaller` for `x86_64` only has a 50 MB size whereas the same application compiled in `universal2` mode has a 250 MB size.<br><b>Take this warning in consideration when compiling bigger applications because their final size can either double or triple!</b>

In order to compile an universal bundle on macOS with PyInstaller, you need to have all your project's requirements and dependencies installed in `universal2` mode and set inside your `.spec` file the target architecture to `universal2`. Read [pyinstaller's documentation](https://pyinstaller.org/en/stable/feature-notes.html#macos-multi-arch-support) for more information.

### `upip`'s Installation logic
When installing a package, `upip` will follow this logic:
### `uPip`'s Installation logic
When installing a package, `uPip` will follow this logic:
- First, check if an `universal2.whl` exists for the given release version.
- If such a release exists, downloads it and installs it
- If no `universal2.whl` distribution exists, checks if a distribution `p3-none-any.whl` exists, meaning that the current packages has no platform specific dependencies.
- If such a release exists, downloads it and installs it
- If neither `universal2.whl` and `p3-none-any.whl` distribution exists, downloads both `macos_10_X_x86_64.whl` and `macosx_11_0_arm64.whl` wheels to fuse them into `macosx_11_0_universal2.whl` and then installs the created wheel.

When the universal2 wheel is installed, `upip` checks the newly installed package's dependencies to also update them if they are not in universal2 mode. The same logic applies for processing package's dependencies as described above.
When the universal2 wheel is installed, `uPip` checks the newly installed package's dependencies to also update them if they are not in universal2 mode. The same logic applies for processing package's dependencies as described above.

### How to uninstall packages installed by `upip`?
There is no specific tool to uninstall packages installed by `upip`. You can use `pip` directly to uninstall any package installed by `upip` as you would normally do for a normal package. Or you can [invoke pip from `upip`](#invoke-pip) to be sure to call the same python version as the one used by `upip`.
### How to uninstall packages installed by `uPip`?
There is no specific tool to uninstall packages installed by `uPip`. You can use `pip` directly to uninstall any package installed by `uPip` as you would normally do for a normal package. Or you can [invoke pip from `uPip`](#invoke-pip) to be sure to call the same python version as the one used by `uPip`.

### Installation
To install the `upip` package, you can use the following command:
To install the `uPip` package, you can use the following command:

```shell
$ pip install upip
$ pip install universalPip
```
To verify the installation, call the `upip` CLI from the terminal:
To verify the installation, call the `uPip` CLI from the terminal:
```shell
$ upip
$ uPip
```
If the CLI is correctly installed, the documentation should show up.

### Usage
#### Install a package
<hr>
Once installed, you can use the `upip` package to install other Python packages. Here's an example:
Once installed, you can use the `uPip` package to install other Python packages. Here's an example:

<br>Let's say we want to install [mzdata2mat](https://github.com/MaximeLeMagicien/mzdata2mat), a package aimed to convert `.mzData.xml` files into `.mat` files. Here is the command to install the package:

```shell
$ upip --install mzdata2mat
$ uPip --install mzdata2mat
```
The installation will be performed into the `site-packages` of the python installation which downloaded `upip` inside the `wheels` folder.<br>
The installation will be performed into the `site-packages` of the python installation which downloaded `uPip` inside the `wheels` folder.<br>

Additionnaly, you can add `--version` tag to specify a release version to install. Command would be:
```shell
$ upip --install mzdata2mat --version "1.0.0"
$ uPip --install mzdata2mat --version "1.0.0"
```
If no version is specified, the latest one will be used.
<hr>

#### Create an universal2 wheel
If you just want to create a wheel without installing it, use the following command:
```shell
$ upip --makeU mzdata2mat
$ uPip --makeU mzdata2mat
```
Same logic for the `--version` tag, either specify it to create an `universal2` wheel or don't specify it and the latest version available will be used.

All created wheels are stored inside `upip`'s install directory in the `site-packages` of the python installation in a folder called `wheels`. If you want to specify a custom path use the following command:
All created wheels are stored inside `uPip`'s install directory in the `site-packages` of the python installation in a folder called `wheels`. If you want to specify a custom path use the following command:
```shell
$ upip --makeU mzdata2mat --destination "path/to/folder"
$ uPip --makeU mzdata2mat --destination "path/to/folder"
```

If `--destination` is not provided, default path will be used.
<hr>

#### Check if a package is universal
To avoid installing twice a package already in `universal2` mode, you can use the verification process of `upip` by using this command:
To avoid installing twice a package already in `universal2` mode, you can use the verification process of `uPip` by using this command:
```shell
$ upip --checkU mzdata2mat
$ uPip --checkU mzdata2mat
```
This command will verify if all `.so` files inside `mzdata2mat` package are in fat mode with both `arm64` and `x86_64` architectures inside.
<hr>

#### Show default stored wheel directory
You can show where is located the `wheels` directory by using this command:
```shell
$ upip --showPath
$ uPip --showPath
```
This will print the default save location.
<hr>

#### Invoke `pip`
You can trigger pip from `upip` CLI by adding this parameter to the command: `--pip`.
You can trigger pip from `uPip` CLI by adding this parameter to the command: `--pip`.
Here is an example:
```shell
$ upip --pip "show mzdata2mat"
$ uPip --pip "show mzdata2mat"
```
One main advantage to use `upip` to call `pip` is to be sure to call the same python version of pip as the one used to run `upip`. For instance, it could be useful to run pip like this in order to uninstall packages.
One main advantage to use `uPip` to call `pip` is to be sure to call the same python version of pip as the one used to run `uPip`. For instance, it could be useful to run pip like this in order to uninstall packages.

<hr>

#### Printing `upip`'s version
To show `upip`'s version use the following command:
#### Printing `uPip`'s version
To show `uPip`'s version use the following command:
```shell
$ upip --V
$ uPip --V
```

<hr>

#### Print documentation
As a normal package, to print `upip`'s documentation in the terminal use the following command:
As a normal package, to print `uPip`'s documentation in the terminal use the following command:
```shell
$ upip -h
$ uPip -h
```
or simply:
```shell
$ upip
$ uPip
```
In fact, if there is no parameters provided with `upip`'s call, documentation is printed by default.
In fact, if there is no parameters provided with `uPip`'s call, documentation is printed by default.
### Contributing
Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the [GitHub repository](https://github.com/MaximeLeMagicien/upip).
Contributions are welcome! If you find any issues or have suggestions for improvements, please open an issue or submit a pull request on the [GitHub repository](https://github.com/MaximeLeMagicien/uPip).

### License
This package is licensed under the MIT License. See the [LICENSE](https://github.com/MaximeLeMagicien/upip/blob/main/LICENSE) file for more details.
This package is licensed under the MIT License. See the [LICENSE](https://github.com/MaximeLeMagicien/uPip/blob/main/LICENSE) file for more details.
Binary file removed dist/upip-0.1.0-py3-none-any.whl
Binary file not shown.
Binary file removed dist/upip-0.1.0.tar.gz
Binary file not shown.
10 changes: 6 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "uPip"
version = "0.1.0"
name = "universalPip"
version = "0.1.1"
description = "Creates an Universal2 distribution for given package on PyPI and installs it."
readme = "README.md"
requires-python = ">=3.8"
Expand All @@ -13,7 +13,7 @@ keywords = [
"macOSX",
"pyinstaller",
"arm64",
"x66_64"
"x86_64"
]
classifiers = [
"Development Status :: 4 - Beta",
Expand All @@ -31,11 +31,13 @@ dependencies = [
]

[project.scripts]
upip = "uPip.cli:processInput"
uPip = "uPip.cli:processInput"

[project.urls]
Homepage = "https://github.com/MaximeLeMagicien/uPip"
Issues = "https://github.com/MaximeLeMagicien/uPip/issues"
Changelog = "https://github.com/MaximeLeMagicien/uPip/blob/main/Changelog.md"


[build-system]
requires = ["hatchling"]
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion src/uPip/cli.py → src/universalPip/cli.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .uPip import PkgManager
from .universalPip import PkgManager
from argparse import ArgumentParser
from subprocess import check_call
import sys
Expand Down
File renamed without changes.

0 comments on commit 100b46a

Please sign in to comment.