diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..820afc3f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,34 @@ +name: CI +on: + workflow_dispatch: + push: + branches: ['main', 'develop'] + pull_request: +jobs: + tests: + runs-on: ${{ matrix.os }} + steps: + - name: Checkout code + uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 + + - name: Setup uv and handle its cache + uses: hynek/setup-cached-uv@49a39f911c85c6ec0c9aadd5a426ae2761afaba2 # v2.0.0 + + - name: "Set up Python" + uses: actions/setup-python@39cd14951b08e74b54015e9e001cdefcf80e669f # v5.1.1 + with: + python-version: ${{ matrix.python-version }} + + - name: Setup dependencies + run: | + uv pip install --system --break-system-packages -r ./.requirements/${{ matrix.python-version }}-${{ runner.os }}.txt + uv pip install --system --break-system-packages pytest pytest-md pytest-emoji + + - name: Run pytest + uses: pavelzw/pytest-action@510c5e90c360a185039bea56ce8b3e7e51a16507 # v2.2.0 + with: + custom-arguments: tests + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + python-version: [3.12] diff --git a/.python-version b/.python-version new file mode 100644 index 00000000..455808f8 --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12.4 diff --git a/.requirements/3.12-Linux.txt b/.requirements/3.12-Linux.txt new file mode 100644 index 00000000..21d8888f --- /dev/null +++ b/.requirements/3.12-Linux.txt @@ -0,0 +1,2 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml --generate-hashes --python-version 3.12 --python-platform linux --output-file .requirements/3.12-Linux.txt diff --git a/.requirements/3.12-Windows.txt b/.requirements/3.12-Windows.txt new file mode 100644 index 00000000..b913d37d --- /dev/null +++ b/.requirements/3.12-Windows.txt @@ -0,0 +1,2 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml --generate-hashes --python-version 3.12 --python-platform windows --output-file .requirements/3.12-Windows.txt diff --git a/.requirements/3.12-macOS.txt b/.requirements/3.12-macOS.txt new file mode 100644 index 00000000..bbf5adb8 --- /dev/null +++ b/.requirements/3.12-macOS.txt @@ -0,0 +1,2 @@ +# This file was autogenerated by uv via the following command: +# uv pip compile pyproject.toml --generate-hashes --python-version 3.12 --python-platform macos --output-file .requirements/3.12-macOS.txt diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..e411a935 --- /dev/null +++ b/Makefile @@ -0,0 +1,5 @@ +.PHONY requirements: +requirements: + uv pip compile "pyproject.toml" --quiet --generate-hashes --python-version 3.12 --python-platform linux --output-file .requirements/3.12-Linux.txt + uv pip compile "pyproject.toml" --quiet --generate-hashes --python-version 3.12 --python-platform macos --output-file .requirements/3.12-macOS.txt + uv pip compile "pyproject.toml" --quiet --generate-hashes --python-version 3.12 --python-platform windows --output-file .requirements/3.12-Windows.txt \ No newline at end of file diff --git a/README.md b/README.md index 49182922..f6115b54 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,7 @@ -# usethis-python +# usethis + Automate Python package and project setup tasks that are otherwise performed manually. + +## Development + +[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) diff --git a/doc/philosophy/introspection.md b/doc/philosophy/introspection.md new file mode 100644 index 00000000..0ba391bb --- /dev/null +++ b/doc/philosophy/introspection.md @@ -0,0 +1,71 @@ +# Introspection when developing + +Nathan McDougall, August 2024. + +When developing, so many of our actions are reflexive. If you are interesting in +developing usethis, then it is very valuable to slow down, and consider thoroughly +which actions you are undertaking. Some of them might be running off-the-shelf automated +tools. Sometimes you might be setting up bespoke configuration for those tools. +Other times, you might have to do something manually. + +These are all useful points to note down and can provide a lot of insight into potential +features for usethis (besides just being useful documentation). + +For example, when developing usethis, here are a list of actions that I undertook (not +necessarily listed chronologically): + +## Toolset decisions + +- Use GitHub Actions for CI. +- Always use the hash to pin the version of a GitHub action `uses:` +- Use uv for package management. + +## Repo configuration + +- Created a repo on GitHub wih template .gitignore, MIT license and README. +- Created a develop branch. +- Set up sensible rulesets for branches. +- Created a template for GitHub issues that are development tasks. +- Created a Makefile. +- Created a `make requirements` command to make platform-specific requirements files. +- Ran `uv init --name usethis`. +- Ran `uv python pin 3.12.4`. +- Created a `.requirements` directory with Python version and OS specific files. + +## Add GitHub Actions CI + +- Create a GitHub workflow file for CI manually in `.github/workflows/ci.yml`. +- Use the following configuration to support GitFlow-style branch management: + +```yml +name: CI +on: + workflow_dispatch: + push: + branches: ['main', 'develop'] + pull_request: +``` + +- Add . +- Add . +- Set up the GitHub actions matrix to use Ubuntu, Windows and MacOS. +- Set up the GitHub actions to use different Python versions. +- Set up logic to use uv in GitHub actions. + +## Local development configuration + +- Cloned the repo from GitHub. +- Ran `uv sync`. +- Set up git username, email, and signing key. + +## Set up tests + +- Ran `uv add --dev pytest`. +- Created a tests folder. +- Added a trivial test module `test_nothing.py`. +- Add a trivial test `test_pass` to the test module. +- Add step to CI to install pytest +- Add step to CI to install pytest-md and pytest-emoji (used by Action). +- Confirm pytest is working with `pytest tests` in the CLI. +- Add to set up pytest in CI, using the + correct CLI args to pytest. diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..4428059d --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[project] +name = "usethis" +version = "0.1.0" +description = "Add your description here" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.uv] +dev-dependencies = ["pytest>=8.3.2"] diff --git a/src/usethis/__init__.py b/src/usethis/__init__.py new file mode 100644 index 00000000..f17db583 --- /dev/null +++ b/src/usethis/__init__.py @@ -0,0 +1,2 @@ +def hello() -> str: + return "Hello from usethis!" diff --git a/tests/test_nothing.py b/tests/test_nothing.py new file mode 100644 index 00000000..a8a8219c --- /dev/null +++ b/tests/test_nothing.py @@ -0,0 +1,2 @@ +def test_pass(): + pass diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..4187c477 --- /dev/null +++ b/uv.lock @@ -0,0 +1,66 @@ +version = 1 +requires-python = ">=3.11" + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "packaging" +version = "24.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pytest" +version = "8.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", size = 1439314 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802 }, +] + +[[package]] +name = "usethis" +version = "0.1.0" +source = { editable = "." } +dependencies = [ + { name = "pytest" }, +] + +[package.dev-dependencies] +dev = [ + { name = "pytest" }, +]