Metadata-Version: 2.4
Name: tar-install
Version: 0.2.0
Summary: Python ctypes bindings for the Linux-only tar-install Rust library.
Home-page: https://github.com/TamKungZ/tarminal-tar-install
Author: TamKungZ_
Author-email: TamKungZ_ <dev@tamkungz.me>
License: MIT
Project-URL: Homepage, https://packages.tamkungz.me/apps/tarminal/
Project-URL: Repository, https://github.com/TamKungZ/tarminal-tar-install
Keywords: tar,appimage,linux,desktop,installer
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: POSIX :: Linux
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Dynamic: author
Dynamic: home-page
Dynamic: requires-python

# tar-install Python bindings

Experimental Python bindings for the Linux-only `tar_install` Rust library.

This package does not use a command-line bridge. Python loads a small bundled
shared library with `ctypes`; that shared library links to the Rust
`tar_install` crate and calls the library API directly.

- No Python native extension is built.
- Linux wheels bundle `libtar_install.so`.
- The `tar-install` binary remains a tiny stub; the human CLI remains
  `tarminal`.
- During development, Python can ask Cargo to build the shared library from a
  source checkout.

The actual installer behavior is Linux desktop oriented, so this package is
Linux only.

## Local dev

```sh
python3 -m venv .venv
. .venv/bin/activate
python -m pip install -U pip
python -m pip install -e .
python - <<'PY'
import tarinstall

tarinstall.build_library()
print(tarinstall.list_apps())
PY
```

## Library resolution

The wrapper finds `libtar_install.so` in this order:

1. `TAR_INSTALL_LIB`
2. bundled `tarinstall/lib/libtar_install.so`
3. `target/release/libtar_install.so`
4. `target/debug/libtar_install.so`

## Build The Shared Library

From the main project root, build the Rust library and `.so` directly:

```sh
cargo build -p tar-install
```

The debug shared library will be written to:

```text
target/debug/libtar_install.so
```

For a release build:

```sh
cargo build -p tar-install --release
```

The release shared library will be written to:

```text
target/release/libtar_install.so
```

This does not change the core installer logic. The `tar-install` crate now
declares both Rust library and shared-library outputs, so Cargo can produce
`libtar_install.so` from the same source. The normal Rust API remains available,
and the `tar-install` binary remains the small stub. The only practical impact
when building the `tar-install` package itself is an extra `.so` artifact and a
little more link time.

Build the local shared library from Python:

```py
import tarinstall

tarinstall.build_library(release=True)
```

## Wheel build

```sh
python -m pip wheel .
```

Wheel builds run `cargo build -p tar-install --release`
and copy the resulting shared library into the Python package. Set
`TAR_INSTALL_SKIP_BUNDLE=1` to build a wrapper wheel without the shared library.

## PyPI publish

PyPI publishing lives in this repository under `.github/workflows/publish.yml`.
The main `tarminal-tar-install` release workflow can trigger it after a tagged
release by sending a `repository_dispatch` event with a token stored as
`PYLIB_WORKFLOW_TOKEN`.

Configure PyPI Trusted Publisher with:

- Project name: `tar-install`
- Owner: `TamKungZ`
- Repository name: `pylib-tar-install`
- Workflow name: `publish.yml`
- Environment name: `pypi`

The publish workflow checks out the requested main project ref, checks out this
Python package at the submodule commit sent by the release workflow, builds
`libtar_install.so` from that source, bundles it into the wheel, smoke tests the
import, and publishes the wheel to PyPI.

The publish workflow sets `TAR_INSTALL_WHEEL_PLAT=manylinux_2_35_x86_64` because
PyPI rejects raw `linux_x86_64` binary wheel tags.

## Library API

```py
import tarinstall

inspection = tarinstall.inspect("some-app-linux-x64.tar.xz")
report = tarinstall.install("some-app-linux-x64.tar.xz", app_id="some-app", force=True)
apps = tarinstall.list_apps()
doctor = tarinstall.doctor("some-app")
removed = tarinstall.remove("some-app")

print(inspection["safe"])
print(report.id, report.command)
print([app.as_dict() for app in apps])
print(doctor.fields)
print(removed.removed_paths)
```

For apps that need more control, create a client:

```py
from tarinstall import TarInstall

tar_install = TarInstall(library="/path/to/libtar_install.so")
inspection = tar_install.inspect("some-app-linux-x64.tar.xz")
```

Use `InstallOptions` when passing install configuration around your own app:

```py
from tarinstall import InstallOptions, TarInstall

tar_install = TarInstall()
options = InstallOptions(
    scope="user",
    app_id="some-app",
    name="Some App",
    command="some-app",
    force=True,
)

report = tar_install.install("some-app-linux-x64.tar.xz", options)
```

If the native library returns an error, `TarInstallError` includes the raw
payload for logs or UI error reporting.
