From dd917d03bc96ace1a604ea2dcc1714da6d6d19c7 Mon Sep 17 00:00:00 2001 From: Yu Ishikawa Date: Wed, 25 Dec 2024 17:15:06 +0900 Subject: [PATCH] Use uv instead of flit (#137) --- .github/workflows/publish.yml | 43 ++++++++------------ .github/workflows/test-publish.yml | 44 +++++++------------- .github/workflows/test.yml | 15 ++++--- Makefile | 4 +- dbt_artifacts_parser/__init__.py | 3 +- dev/build.sh | 19 +++++++++ dev/publish.sh | 24 ++++++----- dev/setup.sh | 55 ++++++++++++++++++++++--- pyproject.toml | 64 ++++++++++++++++-------------- requirements.setup.txt | 1 + setup.py | 17 -------- tests/test_basic.py | 20 ---------- 12 files changed, 160 insertions(+), 149 deletions(-) create mode 100644 dev/build.sh create mode 100644 requirements.setup.txt delete mode 100644 setup.py delete mode 100644 tests/test_basic.py diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ffa095a..2571a73 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,54 +12,43 @@ jobs: run: shell: bash steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.9" - - uses: actions/cache@v4 - id: cache - with: - path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish - - name: Install Flit - if: steps.cache.outputs.cache-hit != 'true' - run: bash dev/setup.sh + - name: Install uv + run: | + pip install -r requirements.setup.txt - name: Publish env: - # SEE https://packaging.python.org/en/latest/specifications/pypirc/?highlight=token#using-a-pypi-token - FLIT_USERNAME: __token__ - FLIT_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - run: bash dev/publish.sh "pypi" - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" + UV_PUBLISH_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" + run: | + bash dev/publish.sh "pypi" test-published-package: needs: - publish runs-on: ubuntu-latest + strategy: + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] defaults: run: shell: bash steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: - python-version: "3.9" - - name: Install packages + python-version: "${{ matrix.python-version }}" + # It takes some time when the package gets available. + - name: Sleep + run: | + sleep 30 + - name: Install package run: | python3 -m pip install -U dbt-artifacts-parser - - name: Test pacakge + - name: Test package run: | python -c 'import dbt_artifacts_parser; print(dbt_artifacts_parser.__version__)' diff --git a/.github/workflows/test-publish.yml b/.github/workflows/test-publish.yml index 2a95680..02054e8 100644 --- a/.github/workflows/test-publish.yml +++ b/.github/workflows/test-publish.yml @@ -7,7 +7,6 @@ on: description: "dbt-artifacts-parser version" required: true - jobs: publish: runs-on: ubuntu-latest @@ -15,49 +14,31 @@ jobs: run: shell: bash steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: "3.9" - - uses: actions/cache@v4 - id: cache - with: - path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-publish - - name: Install Flit - if: steps.cache.outputs.cache-hit != 'true' - run: bash dev/setup.sh + - name: Install uv + run: | + pip install -r requirements.setup.txt - name: Test publish env: - # SEE https://packaging.python.org/en/latest/specifications/pypirc/?highlight=token#using-a-pypi-token - FLIT_USERNAME: __token__ - FLIT_PASSWORD: ${{ secrets.TESTPYPI_API_TOKEN }} - run: bash dev/publish.sh "testpypi" - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" + UV_PUBLISH_TOKEN: "${{ secrets.TESTPYPI_API_TOKEN }}" + run: | + bash dev/publish.sh testpypi test-published-package: needs: - publish runs-on: ubuntu-latest + strategy: + matrix: + python-version: [ "3.8", "3.9", "3.10", "3.11", "3.12" ] defaults: run: shell: bash - strategy: - matrix: - python-version: [ "3.7", "3.8", "3.9", "3.10", "3.11" ] steps: - - name: Dump GitHub context - env: - GITHUB_CONTEXT: ${{ toJson(github) }} - run: echo "$GITHUB_CONTEXT" - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 @@ -68,9 +49,14 @@ jobs: python3 -m pip install -U pip==23.1.0 python3 -m pip install \ --index-url https://test.pypi.org/simple/ \ + --extra-index-url https://pypi.org/simple/ \ --force-reinstall \ --use-feature=fast-deps \ -U dbt-artifacts-parser=="${{ github.event.inputs.dbt_artifacts_parser_version }}" - - name: Test pacakge + # It takes some time when the package gets available. + - name: Sleep + run: | + sleep 30 + - name: Test package run: | python -c 'import dbt_artifacts_parser; print(dbt_artifacts_parser.__version__)' diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc52d6f..afb130b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -30,16 +30,15 @@ jobs: uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - - uses: actions/cache@v4 - id: cache - with: - path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test - - name: Install Flit - if: steps.cache.outputs.cache-hit != 'true' - run: bash dev/setup.sh + - name: Install dependencies + run: | + python -m pip install -r requirements.setup.txt + bash dev/setup.sh --deps "development" - name: Run tests run: bash dev/test_python.sh + - name: Test build + run: | + bash dev/build.sh - name: Test installation run: | pip install -e . diff --git a/Makefile b/Makefile index 9cf9b11..38f378b 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ setup: setup-python setup-pre-commit # Set up the python environment. .PHONY: setup-python setup-python: - bash ./dev/setup.sh --deps "develop" + bash ./dev/setup.sh --deps "development" # Set up the pre-commit hooks. .PHONY: setup-pre-commit @@ -53,7 +53,7 @@ test: # Build the package .PHONY: build build: clean lint test - flit build + bash -x ./dev/build.sh # Clean the environment .PHONY: clean diff --git a/dbt_artifacts_parser/__init__.py b/dbt_artifacts_parser/__init__.py index 8db6a23..0a6166b 100644 --- a/dbt_artifacts_parser/__init__.py +++ b/dbt_artifacts_parser/__init__.py @@ -17,4 +17,5 @@ """ A dbt artifacts parser in python """ -__version__ = "0.8.0" + +__version__ = "0.8.1" diff --git a/dev/build.sh b/dev/build.sh new file mode 100644 index 0000000..dd1833c --- /dev/null +++ b/dev/build.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Copyright 2024 yu-iskw +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -Eo pipefail + +python -m build diff --git a/dev/publish.sh b/dev/publish.sh index 5cba979..c76fe62 100755 --- a/dev/publish.sh +++ b/dev/publish.sh @@ -13,25 +13,29 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -Eo pipefail set -x -SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" +SCRIPT_FILE="$(readlink -f "$0")" +SCRIPT_DIR="$(dirname "$SCRIPT_FILE")" MODULE_DIR="$(dirname "$SCRIPT_DIR")" -cd "$MODULE_DIR" +cd "$MODULE_DIR" || exit # Arguments target=${1:?"target is not set"} -# SEE https://flit.readthedocs.io/en/latest/reproducible.html -SOURCE_DATE_EPOCH=$(date +%s) -export SOURCE_DATE_EPOCH +# Ensure uv is installed +pip install uv -if [[ "$target" == "pypi" ]] ; then - flit publish --repository "${target}" --pypirc "${MODULE_DIR}/.pypirc" --setup-py -elif [[ "$target" == "testpypi" ]] ; then - flit publish --repository "${target}" --pypirc "${MODULE_DIR}/.pypirc" --setup-py +# Build the package first +uv build + +# Publish to the specified target +if [[ "$target" == "pypi" ]]; then + uv publish +elif [[ "$target" == "testpypi" ]]; then + uv publish --publish-url "https://test.pypi.org/legacy/" else echo "No such target ${target}" exit 1 diff --git a/dev/setup.sh b/dev/setup.sh index dc78755..42db382 100755 --- a/dev/setup.sh +++ b/dev/setup.sh @@ -13,14 +13,57 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -set -e +set -Eeuo pipefail # Constants SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" -MODULE_DIR="$(dirname "$SCRIPT_DIR")" +MODULE_DIR="$(dirname "${SCRIPT_DIR}")" -cd "$MODULE_DIR" +# Arguments +deps="production" +use_venv=false +while (($# > 0)); do + if [[ "$1" == "--use-venv" ]]; then + use_venv=true + shift 1 + elif [[ "$1" == "--deps" ]]; then + if [[ "$2" != "production" && "$2" != "development" ]]; then + echo "Error: deps must be one of 'production' or 'development'" + exit 1 + fi + deps="$2" + shift 2 + else + echo "Unknown argument: $1" + exit 1 + fi +done -FLIT_VERSION="3.9.0" -pip install -U flit=="$FLIT_VERSION" -flit install --deps develop --symlink +# Change to the module directory +cd "${MODULE_DIR}" + +# Install uv and dependencies +pip install --force-reinstall -r "${MODULE_DIR}/requirements.setup.txt" + +UV_PIP_OPTIONS=("--force-reinstall") +if [[ "${use_venv}" == true ]]; then + # Create virtual environment + uv venv + # Activate virtual environment + if [[ -f .venv/bin/activate ]]; then + # shellcheck disable=SC1091 + source .venv/bin/activate + else + echo "Error: .venv/bin/activate not found" + exit 1 + fi +else + UV_PIP_OPTIONS+=("--system") +fi + +# Install package and dependencies +if [[ "${deps}" == "production" ]]; then + uv pip install "${UV_PIP_OPTIONS[@]}" -e "." +else + uv pip install "${UV_PIP_OPTIONS[@]}" -e ".[dev,test]" +fi diff --git a/pyproject.toml b/pyproject.toml index ffbe021..fccad2b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,29 +1,13 @@ [build-system] -requires = ["flit_core >=3.2,<4"] -build-backend = "flit_core.buildapi" - -[tool.flit.module] -name = "dbt_artifacts_parser" - -[tool.flit.sdist] -exclude = [ - ".github/", - ".gitignore", - ".pre-commit-config.yaml", - ".style.yapf", - ".pylintrc", - ".pypirc", - "Makefile", - "dev/", - "tests/", -] +requires = ["hatchling"] +build-backend = "hatchling.build" [project] name = "dbt-artifacts-parser" authors = [{name = "yu-iskw"}] readme = "README.md" license = {file = "LICENSE"} -requires-python = ">=3.7.0" +requires-python = ">=3.8.0" classifiers = [ "Development Status :: 4 - Beta", "Intended Audience :: Information Technology", @@ -42,7 +26,8 @@ classifiers = [ "Programming Language :: Python :: 3.12", "Typing :: Typed", ] -dynamic = ["version", "description"] +dynamic = ["version"] +description = "A dbt artifacts parser in python" dependencies = [ "pydantic >=2.0,<3.0", ] @@ -53,21 +38,42 @@ Home = "https://github.com/yu-iskw/dbt-artifacts-parser" [project.optional-dependencies] test = [ "pytest >=6.2.4,<9.0.0", - "pylint >=2.12.0", - "mypy ==1.13.0", - "flake8 >=3.8.3,<4.0.0", - "black ==24.8.0", - "isort >=5.0.6,<6.0.0", - "yapf >=0.29.0", ] dev = [ - "flit ==3.9.0", + "datamodel-code-generator >=0.20,<0.30", "build ==1.2.2", - "yapf >=0.29.0", "pyyaml >=5.3", "pdoc3 >=0.9.2", "pre-commit >=2.15.0", - "datamodel-code-generator >=0.20,<0.30", + "pylint >=2.12.0", + "mypy ==1.13.0", + "flake8 >=3.8.3,<4.0.0", + "black ==24.8.0", + "isort >=5.0.6,<6.0.0", +] + +[tool.hatch.version] +path = "dbt_artifacts_parser/__init__.py" + +[tool.hatch.build.targets.sdist] +exclude = [ + ".github/", + ".gitignore", + ".pre-commit-config.yaml", + ".style.yapf", + ".pylintrc", + ".pypirc", + "Makefile", + "dev/", + "tests/", + ".DS_Store", + ".vscode/", + ".trunk/", + ".pytest_cache/", + ".mypy_cache/", + "dist/", + "test.json", + "renovate.json" ] [tool.isort] diff --git a/requirements.setup.txt b/requirements.setup.txt new file mode 100644 index 0000000..8a0dff1 --- /dev/null +++ b/requirements.setup.txt @@ -0,0 +1 @@ +uv>=0.5,<0.6 diff --git a/setup.py b/setup.py deleted file mode 100644 index e232fe3..0000000 --- a/setup.py +++ /dev/null @@ -1,17 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -from setuptools import setup - -setup() diff --git a/tests/test_basic.py b/tests/test_basic.py deleted file mode 100644 index 915683b..0000000 --- a/tests/test_basic.py +++ /dev/null @@ -1,20 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one or more -# contributor license agreements. See the NOTICE file distributed with -# this work for additional information regarding copyright ownership. -# The ASF licenses this file to You under the Apache License, Version 2.0 -# (the "License"); you may not use this file except in compliance with -# the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -import dbt_artifacts_parser - - -class TestBasicInformation: - def test_version(self): - assert dbt_artifacts_parser.__version__ is not None