Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 17 additions & 40 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,58 +33,34 @@ jobs:
if: steps.changes.outputs.docs == 'true' || steps.changes.outputs.root_docs == 'true' || steps.changes.outputs.python_files == 'true'
run: echo "PUBLISH=$(echo true)" >> $GITHUB_ENV

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Get full Python version
id: full-python-version
shell: bash
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")

- name: Install poetry
run: |
curl -O -sSL https://install.python-poetry.org/install-poetry.py
python install-poetry.py -y --version 1.1.14
echo "PATH=${HOME}/.poetry/bin:${PATH}" >> $GITHUB_ENV
rm install-poetry.py
if: env.PUBLISH == 'true'
run: pipx install "poetry==1.1.14"

- name: Add ~/.local/bin to PATH
run: echo "$HOME/.local/bin" >> $GITHUB_PATH

- name: Get poetry cache paths from config
run: |
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV

- name: Configure poetry
shell: bash
run: poetry config virtualenvs.in-project true

- name: Set up cache
uses: actions/cache@v3
id: cache
- name: Set up Python ${{ matrix.python-version }}
if: env.PUBLISH == 'true'
uses: actions/setup-python@v4
with:
path: |
.venv
{{ env.poetry_cache_dir }}
{{ env.poetry_virtualenvs_path }}
key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }}

- name: Ensure cache is healthy
if: steps.cache.outputs.cache-hit == 'true'
shell: bash
run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv
python-version: ${{ matrix.python-version }}
cache: 'poetry'

- name: Install dependencies [w/ docs]
if: env.PUBLISH == 'true'
run: poetry install --extras "docs lint"

- name: Print python versions
if: env.PUBLISH == 'true'
run: |
python -V
poetry run python -V

- name: Build documentation
if: env.PUBLISH == 'true'
run: |
pushd docs; make SPHINXBUILD='poetry run sphinx-build' html; popd

- name: Push documentation to S3
if: env.PUBLISH == 'true'
uses: jakejarvis/[email protected]
with:
args: --acl public-read --follow-symlinks --delete
Expand All @@ -96,6 +72,7 @@ jobs:
SOURCE_DIR: "docs/_build/html" # optional: defaults to entire repository

- name: Purge cache on Cloudflare
if: env.PUBLISH == 'true'
uses: jakejarvis/cloudflare-purge-action@master
env:
CLOUDFLARE_TOKEN: ${{ secrets.CLOUDFLARE_TOKEN }}
Expand Down
52 changes: 13 additions & 39 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,56 +12,30 @@ jobs:
python-version: ["3.7", "3.10"]
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v3
with:
python-version: ${{ matrix.python-version }}

- name: Get full Python version
id: full-python-version
shell: bash
run: echo ::set-output name=version::$(python -c "import sys; print('-'.join(str(v) for v in sys.version_info))")

- name: Install poetry
run: |
curl -O -sSL https://install.python-poetry.org/install-poetry.py
python install-poetry.py -y --version 1.1.14
echo "PATH=${HOME}/.poetry/bin:${PATH}" >> $GITHUB_ENV
rm install-poetry.py

- name: Add ~/.local/bin to PATH
run: echo "$HOME/.local/bin" >> $GITHUB_PATH

- name: Get poetry cache paths from config
run: |
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
echo "poetry_virtualenvs_path=$(poetry config --list | sed -n 's/.*virtualenvs.path = .* # //p' | sed -e 's/^\"//' -e 's/\"$//')" >> $GITHUB_ENV
run: pipx install "poetry==1.1.14"

- name: Configure poetry
shell: bash
run: poetry config virtualenvs.in-project true

- name: Set up cache
uses: actions/cache@v3
id: cache
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
path: |
.venv
${{ env.poetry_cache_dir }}
${{ env.poetry_virtualenvs_path }}
key: venv-${{ runner.os }}-${{ steps.full-python-version.outputs.version }}-${{ hashFiles('**/poetry.lock') }}

- name: Ensure cache is healthy
if: steps.cache.outputs.cache-hit == 'true'
shell: bash
run: poetry run pip --version >/dev/null 2>&1 || rm -rf .venv
python-version: ${{ matrix.python-version }}
cache: 'poetry'

- name: Install dependencies
run: poetry install -E "docs test coverage lint format"

- name: Print python versions
run: |
python -V
poetry run python -V

- name: Lint with flake8
run: poetry run flake8

- name: Lint with mypy
run: poetry run mypy .

- name: Test with pytest
run: poetry run py.test --cov=./ --cov-report=xml

Expand Down
15 changes: 0 additions & 15 deletions .pre-commit-config.yaml

This file was deleted.

23 changes: 22 additions & 1 deletion CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,31 @@ $ pipx install --suffix=@next 'g' --pip-args '\--pre' --force
// Usage: g@next --help
```

## current - unrelased
## g 0.0.1 (unreleased)

- _Add your latest changes from PRs here_

### Development

Infrastructure updates for static type checking and doctest examples.

- Update development packages (black, isort)
- Add .tool-versions, .python-version
- Run code through black w/o `--skip-string-normalization`

- Initial [doctests] support added, via #2

[doctests]: https://docs.python.org/3/library/doctest.html

- Initial [mypy] validation, via #2

[mypy]: https://github.com/python/mypy

- CI (tests, docs): Improve caching of python dependencies via
`action/setup-python`'s v3/4's new poetry caching, via #2

- CI (docs): Skip if no `PUBLISH` condition triggered, via #2

## g 0.0.0 (2022-02-26)

### Documentation
Expand Down
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ watch_mypy:

format_markdown:
prettier --parser=markdown -w *.md docs/*.md docs/**/*.md CHANGES

monkeytype_create:
poetry run monkeytype run `poetry run which py.test`

monkeytype_apply:
poetry run monkeytype list-modules | xargs -n1 -I{} sh -c 'poetry run monkeytype apply {}'
37 changes: 17 additions & 20 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
# flake8: noqa E501
import inspect
import os
import sys
import typing as t
from os.path import dirname, relpath
from pathlib import Path

import g

# Get the project root dir, which is the parent dir of this
cwd = Path.cwd()
cwd = Path(__file__).parent
project_root = cwd.parent

sys.path.insert(0, str(project_root))
sys.path.insert(0, str(cwd / "_ext"))

# package data
about = {}
with open("../g/__about__.py") as fp:
about: t.Dict[str, str] = {}
with open(project_root / "g" / "__about__.py") as fp:
exec(fp.read(), about)

extensions = [
Expand All @@ -31,11 +36,6 @@
]
myst_enable_extensions = ["colon_fence", "substitution", "replacements"]

# app setup hook
def setup(app):
pass


issues_github_path = about["__github__"].replace("https://github.com/", "")
templates_path = ["_templates"]

Expand All @@ -59,8 +59,8 @@ def setup(app):
html_css_files = ["css/custom.css"]
html_extra_path = ["manifest.json"]
html_theme = "furo"
html_theme_path = []
html_theme_options = {
html_theme_path: t.List[str] = []
html_theme_options: t.Dict[str, t.Union[str, t.List[t.Dict[str, str]]]] = {
"light_logo": "img/g.svg",
"dark_logo": "img/g-dark.svg",
"footer_icons": [
Expand Down Expand Up @@ -144,13 +144,9 @@ def setup(app):
}


def linkcode_resolve(domain, info): # NOQA: C901
import inspect
import sys
from os.path import dirname, relpath

import g

def linkcode_resolve(
domain: str, info: t.Dict[str, str]
) -> t.Union[None, str]: # NOQA: C901
"""
Determine the URL corresponding to Python object

Expand Down Expand Up @@ -183,7 +179,8 @@ def linkcode_resolve(domain, info): # NOQA: C901
except AttributeError:
pass
else:
obj = unwrap(obj)
if callable(obj):
obj = unwrap(obj)

try:
fn = inspect.getsourcefile(obj)
Expand All @@ -205,14 +202,14 @@ def linkcode_resolve(domain, info): # NOQA: C901
fn = relpath(fn, start=dirname(g.__file__))

if "dev" in about["__version__"]:
return "%s/blob/master/%s/%s%s" % (
return "{}/blob/master/{}/{}{}".format(
about["__github__"],
about["__package_name__"],
fn,
linespec,
)
else:
return "%s/blob/v%s/%s/%s%s" % (
return "{}/blob/v{}/{}/{}{}".format(
about["__github__"],
about["__version__"],
about["__package_name__"],
Expand Down
28 changes: 23 additions & 5 deletions g/__init__.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,51 @@
#!/usr/bin/env python

import pathlib
import subprocess
import sys
import typing as t
from os import PathLike

__all__ = ["sys", "vcspath_registry", "DEFAULT", "run"]

vcspath_registry = {".git": "git", ".svn": "svn", ".hg": "hg"}


def find_repo_type(path):
def find_repo_type(path: t.Union[pathlib.Path, str]) -> t.Optional[str]:
for path in list(pathlib.Path(path).parents) + [pathlib.Path(path)]:
for p in path.iterdir():
if p.is_dir():
if p.name in vcspath_registry:
return vcspath_registry[p.name]
return None


DEFAULT = object()


def run(cmd=DEFAULT, cmd_args=DEFAULT, *args, **kwargs):
def run(
cmd: t.Union[str, bytes, "PathLike[str]", "PathLike[bytes]", object] = DEFAULT,
cmd_args: object = DEFAULT,
wait: bool = False,
*args: object,
**kwargs: t.Any
) -> t.Optional["subprocess.Popen[str]"]:
# Interpret default kwargs lazily for mockability of argv
if cmd is DEFAULT:
cmd = find_repo_type(pathlib.Path.cwd())
if cmd_args is DEFAULT:
cmd_args = sys.argv[1:]
proc = subprocess.Popen([cmd, *cmd_args])
proc.communicate()

assert isinstance(cmd_args, (tuple, list))
assert isinstance(cmd, (str, bytes, pathlib.Path))

proc = subprocess.Popen([cmd, *cmd_args], **kwargs)
if wait:
proc.wait()
else:
proc.communicate()
if __name__ != "__main__":
return proc
return None


if __name__ == "__main__":
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ coverage = ["codecov", "coverage", "pytest-cov"]
format = ["black", "isort"]
lint = ["flake8", "mypy"]

[tool.mypy]
strict = true

[build-system]
requires = ["poetry_core>=1.0.0", "setuptools>60"]
build-backend = "poetry.core.masonry.api"
8 changes: 8 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,11 @@ known_pytest = pytest,py
known_first_party = g
sections = FUTURE,STDLIB,PYTEST,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
line_length = 88

[tool:pytest]
addopts = --tb=short --no-header --showlocals --doctest-modules
doctest_optionflags = ELLIPSIS NORMALIZE_WHITESPACE
testpaths =
g
tests
docs
Loading