From 6b807d17e136e172412f785eef59ec56374be980 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 10 Sep 2023 12:23:59 +0900 Subject: [PATCH 1/4] build: add `setup.py` --- .github/workflows/release.yml | 23 ++++++++------ pyproject.toml | 15 +-------- setup.py | 57 +++++++++++++++++++++++++++++++++++ 3 files changed, 72 insertions(+), 23 deletions(-) create mode 100644 setup.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 83ebd54..0a3aa11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -30,12 +30,12 @@ jobs: strategy: matrix: include: - # - target: armv7-unknown-linux-gnueabihf - # os: ubuntu-latest - # - target: aarch64-unknown-linux-gnu - # os: ubuntu-latest - # - target: aarch64-apple-darwin - # os: macos-latest + - target: armv7-unknown-linux-gnueabihf + os: ubuntu-latest + - target: aarch64-unknown-linux-gnu + os: ubuntu-latest + - target: aarch64-apple-darwin + os: macos-latest - target: x86_64-unknown-linux-gnu os: ubuntu-latest - target: x86_64-apple-darwin @@ -47,14 +47,19 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" - name: setup-tools run: | rustup update stable - rustup target add ${{ matrix.target }} - pip3 install maturin + pip3 install twine build + # rustup target add ${{ matrix.target }} - name: upload run: | - maturin publish -u mtshiba -p ${{ secrets.PYPI_PASSWORD }} --target ${{ matrix.target }} --skip-existing + python3 -m build --wheel + twine upload -u mtshiba -p ${{ secrets.PYPI_PASSWORD }} dist/* + # maturin publish -u mtshiba -p ${{ secrets.PYPI_PASSWORD }} --target ${{ matrix.target }} --skip-existing upload-assets: needs: create-release strategy: diff --git a/pyproject.toml b/pyproject.toml index d63e938..923975f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,2 @@ [build-system] -requires = ["maturin>=0.12"] -build-backend = "maturin" - -[project] -name = "pylyzer" -description = "A fast static code analyzer & language server for Python" -requires-python = ">=3.7" -classifiers = [ - "Development Status :: 2 - Pre-Alpha", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Rust", - "Topic :: Software Development :: Quality Assurance", -] +requires = ["setuptools", "setuptools-rust", "wheel"] diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2ec3787 --- /dev/null +++ b/setup.py @@ -0,0 +1,57 @@ +from pathlib import Path +import os +import shlex +from glob import glob +import tomllib + +from setuptools import setup +from setuptools_rust import RustBin + +with open("README.md", encoding="utf-8", errors="ignore") as fp: + long_description = fp.read() + +with open("Cargo.toml", "rb") as fp: + toml = tomllib.load(fp) + name = toml["package"]["name"] + description = toml["package"]["description"] + version = toml["workspace"]["package"]["version"] + license = toml["workspace"]["package"]["license"] + url = toml["workspace"]["package"]["repository"] + +cargo_args = ["--no-default-features"] + +home = os.path.expanduser("~") +file_and_dirs = glob(".erg/lib/**", recursive=True, root_dir=home) +paths = [Path(home + "/" + path) for path in file_and_dirs if os.path.isfile(home + "/" + path)] +files = [(str(path).removesuffix("/" + path.name).removeprefix(home + "/"), str(path)) for path in paths] +data_files = {} +for key, value in files: + if key in data_files: + data_files[key].append(value) + else: + data_files[key] = [value] +data_files = list(data_files.items()) + +setup( + name=name, + author="mtshiba", + author_email="sbym1346@gmail.com", + url=url, + description=description, + long_description=long_description, + long_description_content_type="text/markdown", + version=version, + license=license, + python_requires=">=3", + rust_extensions=[ + RustBin("pylyzer", args=cargo_args, cargo_manifest_args=["--locked"]) + ], + classifiers=[ + "Development Status :: 2 - Pre-Alpha", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Programming Language :: Rust", + "Topic :: Software Development :: Quality Assurance", + ], + data_files=data_files, +) From 75be1077dbd361c2d5ce6568656ace51e8d38ed6 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 10 Sep 2023 12:44:47 +0900 Subject: [PATCH 2/4] chore: add `clean` option --- README.md | 18 ++++++------------ setup.py | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 201b629..36099ef 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ ## Installation +### pip + +```bash +pip install pylyzer +``` + ### cargo (rust package manager) ```bash @@ -25,18 +31,6 @@ cargo install --path . Make sure that `cargo/rustc` is up-to-date, as pylyzer may be written with the latest language features. -### pip - -```bash -pip install pylyzer -``` - -__If installed this way, you also need to [install Erg](https://github.com/mtshiba/ergup).__ - -```bash -curl -L https://github.com/mtshiba/ergup/raw/main/ergup.py | python3 -``` - ### [GitHub Releases](https://github.com/mtshiba/pylyzer/releases/latest) ## What is the advantage over pylint, pyright, pytype, etc.? diff --git a/setup.py b/setup.py index 2ec3787..1b6eb01 100644 --- a/setup.py +++ b/setup.py @@ -3,10 +3,22 @@ import shlex from glob import glob import tomllib +import shutil -from setuptools import setup +from setuptools import setup, Command from setuptools_rust import RustBin +class Clean(Command): + user_options = [] + def initialize_options(self): + pass + def finalize_options(self): + pass + def run(self): + # super().run() + for d in ["build", "dist", "src/pylyzer.egg-info"]: + shutil.rmtree(d, ignore_errors=True) + with open("README.md", encoding="utf-8", errors="ignore") as fp: long_description = fp.read() @@ -23,7 +35,7 @@ home = os.path.expanduser("~") file_and_dirs = glob(".erg/lib/**", recursive=True, root_dir=home) paths = [Path(home + "/" + path) for path in file_and_dirs if os.path.isfile(home + "/" + path)] -files = [(str(path).removesuffix("/" + path.name).removeprefix(home + "/"), str(path)) for path in paths] +files = [(str(path).removesuffix("/" + path.name).removeprefix(home), str(path)) for path in paths] data_files = {} for key, value in files: if key in data_files: @@ -46,6 +58,9 @@ rust_extensions=[ RustBin("pylyzer", args=cargo_args, cargo_manifest_args=["--locked"]) ], + cmdclass={ + "clean": Clean, + }, classifiers=[ "Development Status :: 2 - Pre-Alpha", "Operating System :: OS Independent", From 80ab984b6dce2b2645ef19b9d769786454dc292d Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 10 Sep 2023 13:10:16 +0900 Subject: [PATCH 3/4] feat: copy `.erg` --- src/copy.rs | 38 ++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 4 ++++ 3 files changed, 43 insertions(+) create mode 100644 src/copy.rs diff --git a/src/copy.rs b/src/copy.rs new file mode 100644 index 0000000..353c543 --- /dev/null +++ b/src/copy.rs @@ -0,0 +1,38 @@ +use std::path::Path; +use std::fs::{copy, read_dir, create_dir_all}; + +use erg_common::env::{erg_path, python_site_packages}; + +fn copy_dir(from: impl AsRef, to: impl AsRef) -> std::io::Result<()> { + let from = from.as_ref(); + let to = to.as_ref(); + if !from.exists() { + return Ok(()); + } + if !to.exists() { + create_dir_all(to)?; + } + for entry in read_dir(from)? { + let entry = entry?; + if entry.file_type()?.is_dir() { + copy_dir(entry.path(), to.join(entry.file_name()))?; + } else { + copy(entry.path(), to.join(entry.file_name()))?; + } + } + Ok(()) +} + +#[allow(unused)] +pub(crate) fn copy_dot_erg() { + if erg_path().exists() { + return; + } + for site_packages in python_site_packages() { + if site_packages.join(".erg").exists() { + println!("Copying site-package/.erg to {}", erg_path().display()); + copy_dir(site_packages.join(".erg"), erg_path()) + .expect("Failed to copy .erg"); + } + } +} diff --git a/src/lib.rs b/src/lib.rs index f83b4e6..ff4fa97 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ mod analyze; mod config; mod handle_err; +mod copy; pub use analyze::PythonAnalyzer; diff --git a/src/main.rs b/src/main.rs index 06edf37..775caea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,17 @@ mod analyze; mod config; mod handle_err; +mod copy; use analyze::{PythonAnalyzer, SimplePythonParser}; use els::Server; use erg_common::config::ErgMode; use erg_common::spawn::exec_new_thread; +use crate::copy::copy_dot_erg; + fn run() { + copy_dot_erg(); let cfg = config::parse_args(); if cfg.mode == ErgMode::LanguageServer { let mut lang_server = Server::::new(cfg, None); From b69ce845878caf51cdef93ed9030c69d2d486548 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 10 Sep 2023 13:22:46 +0900 Subject: [PATCH 4/4] Update release.yml --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0a3aa11..130b754 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -57,6 +57,7 @@ jobs: # rustup target add ${{ matrix.target }} - name: upload run: | + cargo build --release python3 -m build --wheel twine upload -u mtshiba -p ${{ secrets.PYPI_PASSWORD }} dist/* # maturin publish -u mtshiba -p ${{ secrets.PYPI_PASSWORD }} --target ${{ matrix.target }} --skip-existing