Skip to content

Commit

Permalink
Refactor - better underscore / hyphenated handling, pypi publish work…
Browse files Browse the repository at this point in the history
…flow (#17)
  • Loading branch information
arthanson authored Apr 8, 2024
1 parent a3d0f81 commit c1d4c29
Show file tree
Hide file tree
Showing 50 changed files with 796 additions and 205 deletions.
2 changes: 2 additions & 0 deletions .flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 120
14 changes: 1 addition & 13 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,8 @@ ci:
autofix_commit_msg: "style: pre-commit fixes"

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
- id: check-merge-conflict
- id: check-symlinks
- id: end-of-file-fixer
- id: mixed-line-ending
- id: requirements-txt-fixer
- id: trailing-whitespace

- repo: https://github.com/mgedmin/check-manifest
rev: "0.47"
rev: "0.49"
hooks:
- id: check-manifest
stages: [manual]
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ bake:
cookiecutter $(BAKE_OPTIONS) . --overwrite-if-exists

watch: bake
watchmedo shell-command -p '*.*' -c 'make bake -e BAKE_OPTIONS=$(BAKE_OPTIONS)' -W -R -D \{{cookiecutter.project_slug}}/
watchmedo shell-command -p '*.*' -c 'make bake -e BAKE_OPTIONS=$(BAKE_OPTIONS)' -W -R -D \{{cookiecutter.underscored}}/

replay: BAKE_OPTIONS=--replay
replay: watch
Expand Down
9 changes: 5 additions & 4 deletions cookiecutter.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
{
"plugin_name": "ACL",
"project_name": "NetBox {{ cookiecutter.plugin_name }} Plugin",
"project_slug": "{{ cookiecutter.project_name.lower().replace(' ', '_').replace('-', '_') }}",
"hyphenated": "{{ '-'.join(cookiecutter['project_name'].lower().split()).replace('_', '-') }}",
"underscored": "{{ cookiecutter.hyphenated.replace('-', '_') }}",
"project_short_description": "NetBox plugin for {{ cookiecutter.plugin_name }}.",
"__model_name": "{{ cookiecutter.plugin_name.replace(' ', '').replace('-', '') }}",
"__model_url": "{{ cookiecutter.plugin_name.lower().replace(' ', '-').replace('_', '-') }}",
"__model_url_name": "{{ cookiecutter.plugin_name.lower().replace(' ', '').replace('_', '').replace('-', '') }}",
"full_name": "Arthur Hanson",
"email": "[email protected]",
"github_username": "arthanson",
"full_name": "John Doe",
"email": "",
"github_username": "",
"version": "0.1.0",
"open_source_license": ["Apache-2.0", "MIT", "BSD", "ISC", "GPL-3.0-only", "Not open source"],
"_copy_without_render": ["docs/changelog.md", "docs/contributing.md", "docs/index.md", ".github/workflows/*.yml"]
Expand Down
5 changes: 4 additions & 1 deletion docs/prompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,13 @@ to initialize most of the other settings.</dd>
<dd>The name of your new Python package project. This is used in
documentation, so spaces and any characters are fine here.</dd>

<dt>project_slug</dt>
<dt>hyphenated</dt>
<dd>The name of your Python package for PyPI, also as the repository name of GitHub.
Typically, it is the slugified version of project_name.</dd>

<dt>underscored</dt>
<dd>The name of the python module and directory in the project.</dd>

<dt>project_short_description</dt>
<dd>A 1-sentence description of what your Python package does.</dd>

Expand Down
8 changes: 4 additions & 4 deletions docs/tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ cookiecutter https://github.com/netbox-community/cookiecutter-netbox-plugin.git
```

Finally, a new folder will be created under current folder, the name is the answer you
provided to `project_slug`.
provided to `hyphenated`.

Go to this generated folder, the project layout should look like:

Expand Down Expand Up @@ -94,7 +94,7 @@ At this point you can run tests and make sure everything is working properly.
## Step 5: Create a GitHub Repo

Go to your GitHub account and create a new repo named `netbox-healthcheck-plugin`, where
`netbox-healthcheck-plugin` matches the `project_slug` from your answers to running
`netbox-healthcheck-plugin` matches the `hyphenated` from your answers to running
cookiecutter.

Then go to repo > settings > secrets, click on 'New repository secret', add the following
Expand All @@ -106,7 +106,7 @@ Then go to repo > settings > secrets, click on 'New repository secret', add the

## Step 6: Upload code to GitHub

Back to your develop environment, find the folder named after the `project_slug`.
Back to your develop environment, find the folder named after the `hyphenated`.
Move into this folder, and then setup git to use your GitHub repo and upload the
code:

Expand Down Expand Up @@ -140,7 +140,7 @@ click on actions link, you should find screen like this:
![](http://images.jieyu.ai/images/202104/20210419170304.png)

There should be some workflows running. After they finished, go to [TestPyPI], check if a
new artifact is published under the name `project_slug`.
new artifact is published under the name `hyphenated`.

## Step 7. Check documentation

Expand Down
2 changes: 1 addition & 1 deletion hooks/pre_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

MODULE_REGEX = r"^[_a-zA-Z][_a-zA-Z0-9]+$"

module_name = "{{ cookiecutter.project_slug}}"
module_name = "{{ cookiecutter.underscored}}"

if not re.match(MODULE_REGEX, module_name):
print(
Expand Down
26 changes: 10 additions & 16 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
# https://www.python.org/dev/peps/pep-0518/

[build-system]
requires = ["setuptools>=63.2.0", "wheel"]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "cookiecutter-netbox-plugin"
version = "0.1.0"
authors = [
{name = "Arthur Hanson", email = "[email protected]"},
]
Expand All @@ -17,24 +19,22 @@ classifiers=[
'Intended Audience :: Developers',
'Natural Language :: English',
"Programming Language :: Python :: 3 :: Only",
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
]

requires-python = ">=3.8"
dynamic = ["version"]

[project.optional-dependencies]
test = [
"black==23.3.0",
"black==24.3.0",
"check-manifest==0.49",
"pre-commit==3.3.1",
"pylint==2.17.4",
"pytest-mock<3.10.1",
"pytest-runner",
"pytest==7.3.1",
"pre-commit==3.7.0",
"pytest==8.1.1",
"flake8",
"flake8-pyproject",
"pytest-github-actions-annotate-failures",
]

Expand All @@ -45,10 +45,4 @@ Tracker = "https://github.com/netbox-community/cookiecutter-netbox-plugin/issues

[tool.black]
line-length = 120
target_version = ['py38', 'py39', 'py310', 'py311']

[tool.isort]
profile = "black"

[tool.pylint]
max-line-length = 120
target-version = ['py312']
12 changes: 6 additions & 6 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
black==23.9.1
bump2version==1.0.1
cookiecutter>=2.3.1
isort==5.12.0
pytest==5.3.1
pytest-cookies==0.5.1
black==24.3.0
flake8==7.0.0
pip==24.0
check-manifest==0.49
pytest==8.1.1
pytest-cookies==0.7.0
19 changes: 4 additions & 15 deletions tests/test_bake_project.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,12 @@
from __future__ import annotations

import datetime
import importlib
import os
import shlex
import subprocess
import sys
from contextlib import contextmanager

import pytest
import yaml
from click.testing import CliRunner
from cookiecutter.utils import rmtree


Expand Down Expand Up @@ -94,9 +90,7 @@ def test_bake_and_run_tests(cookies):

def test_bake_withspecialchars_and_run_tests(cookies):
"""Ensure that a `full_name` with double quotes does not break setup.py"""
with bake_in_temp_dir(
cookies, extra_context={"full_name": 'name "quote" name'}
) as result:
with bake_in_temp_dir(cookies, extra_context={"full_name": 'name "quote" name'}) as result:
assert result.project.isdir()
run_inside_dir("python setup.py test", str(result.project)) == 0

Expand All @@ -119,24 +113,19 @@ def test_make_help(cookies):
def test_bake_selecting_license(cookies):
license_strings = {
"MIT license": "MIT ",
"BSD license": "Redistributions of source code must retain the "
+ "above copyright notice, this",
"BSD license": "Redistributions of source code must retain the " + "above copyright notice, this",
"ISC license": "ISC License",
"Apache Software License 2.0": "Licensed under the Apache License, Version 2.0",
"GNU General Public License v3": "GNU GENERAL PUBLIC LICENSE",
}
for license, target_string in license_strings.items():
with bake_in_temp_dir(
cookies, extra_context={"open_source_license": license}
) as result:
with bake_in_temp_dir(cookies, extra_context={"open_source_license": license}) as result:
assert target_string in result.project.join("LICENSE").read()
assert license in result.project.join("setup.py").read()


def test_bake_not_open_source(cookies):
with bake_in_temp_dir(
cookies, extra_context={"open_source_license": "Not open source"}
) as result:
with bake_in_temp_dir(cookies, extra_context={"open_source_license": "Not open source"}) as result:
found_toplevel_files = [f.basename for f in result.project.listdir()]
assert "setup.py" in found_toplevel_files
assert "LICENSE" not in found_toplevel_files
Expand Down
12 changes: 12 additions & 0 deletions {{cookiecutter.hyphenated}}/.devcontainer/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM mcr.microsoft.com/devcontainers/python:3

RUN python -m pip install --upgrade pip \
&& python -m pip install 'flit>=3.8.0'

ENV FLIT_ROOT_INSTALL=1

COPY pyproject.toml .
RUN touch README.md \
&& mkdir -p src/python_package \
&& python -m flit install --only-deps --deps develop \
&& rm -r pyproject.toml README.md src
44 changes: 44 additions & 0 deletions {{cookiecutter.hyphenated}}/.devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.222.0/containers/python-3-miniconda
{
"name": "Python Environment",
"build": {
"dockerfile": "Dockerfile",
"context": ".."
},
"customizations": {
"vscode": {
"extensions": [
"editorconfig.editorconfig",
"github.vscode-pull-request-github",
"ms-azuretools.vscode-docker",
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.pylint",
"ms-python.isort",
"ms-python.flake8",
"ms-python.black-formatter",
"ms-vsliveshare.vsliveshare",
"ryanluker.vscode-coverage-gutters",
"bungcip.better-toml",
"GitHub.copilot"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"black-formatter.path": [
"/usr/local/py-utils/bin/black"
],
"pylint.path": [
"/usr/local/py-utils/bin/pylint"
],
"flake8.path": [
"/usr/local/py-utils/bin/flake8"
],
"isort.path": [
"/usr/local/py-utils/bin/isort"
]
}
}
},
"onCreateCommand": "pre-commit install-hooks"
}
File renamed without changes.
2 changes: 2 additions & 0 deletions {{cookiecutter.hyphenated}}/.flake8
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[flake8]
max-line-length = 120
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
blank_issues_enabled: false
contact_links:
- name: 📖 Contributing Policy
url: https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}/blob/main/CONTRIBUTING.md
url: https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.hyphenated }}/blob/main/CONTRIBUTING.md
about: "Please read through our contributing policy before opening an issue or pull request."
- name: ❓ Discussion
url: https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.project_slug }}/discussions
url: https://github.com/{{ cookiecutter.github_username }}/{{ cookiecutter.hyphenated }}/discussions
about: "If you're just looking for help, try starting a discussion instead."
- name: 💬 Community Slack
url: https://netdev.chat
Expand Down
51 changes: 51 additions & 0 deletions {{cookiecutter.hyphenated}}/.github/workflows/publish-pypi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# see: https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
name: Publish Python 🐍 distribution 📦 to PyPI

on: push

jobs:
build:
name: Build distribution 📦
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/[email protected]
with:
python-version: "3.x"
- name: Install pypa/build
run: >-
python3 -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: python3 -m build
- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

publish-to-pypi:
name: >-
Publish Python 🐍 distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
needs:
- build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/{{ cookiecutter.hyphenated }}
permissions:
id-token: write # IMPORTANT: mandatory for trusted publishing

steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Loading

0 comments on commit c1d4c29

Please sign in to comment.