diff options
38 files changed, 1275 insertions, 0 deletions
diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..b78ec49 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,77 @@ +version: '{branch}-{build}' +build: off +image: Visual Studio 2019 +environment: + matrix: + - TOXENV: check + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' + - TOXENV: py36,codecov + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' + - TOXENV: py36,codecov + TOXPYTHON: C:\Python36-x64\python.exe + PYTHON_HOME: C:\Python36-x64 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '64' + - TOXENV: py37,codecov + TOXPYTHON: C:\Python37\python.exe + PYTHON_HOME: C:\Python37 + PYTHON_VERSION: '3.7' + PYTHON_ARCH: '32' + - TOXENV: py37,codecov + TOXPYTHON: C:\Python37-x64\python.exe + PYTHON_HOME: C:\Python37-x64 + PYTHON_VERSION: '3.7' + PYTHON_ARCH: '64' + - TOXENV: py38,codecov + TOXPYTHON: C:\Python38\python.exe + PYTHON_HOME: C:\Python38 + PYTHON_VERSION: '3.8' + PYTHON_ARCH: '32' + - TOXENV: py38,codecov + TOXPYTHON: C:\Python38-x64\python.exe + PYTHON_HOME: C:\Python38-x64 + PYTHON_VERSION: '3.8' + PYTHON_ARCH: '64' + - TOXENV: py39,codecov + TOXPYTHON: C:\Python39\python.exe + PYTHON_HOME: C:\Python39 + PYTHON_VERSION: '3.9' + PYTHON_ARCH: '32' + - TOXENV: py39,codecov + TOXPYTHON: C:\Python39-x64\python.exe + PYTHON_HOME: C:\Python39-x64 + PYTHON_VERSION: '3.9' + PYTHON_ARCH: '64' + - TOXENV: py310,codecov + TOXPYTHON: C:\Python31\python.exe + PYTHON_HOME: C:\Python31 + PYTHON_VERSION: '3.1' + PYTHON_ARCH: '32' + - TOXENV: py310,codecov + TOXPYTHON: C:\Python31-x64\python.exe + PYTHON_HOME: C:\Python31-x64 + PYTHON_VERSION: '3.1' + PYTHON_ARCH: '64' +init: + - ps: echo $env:TOXENV + - ps: ls C:\Python* +install: + - '%PYTHON_HOME%\python -mpip install --progress-bar=off tox -rci/requirements.txt' + - '%PYTHON_HOME%\Scripts\virtualenv --version' + - '%PYTHON_HOME%\Scripts\pip --version' + - '%PYTHON_HOME%\Scripts\tox --version' +test_script: + - %PYTHON_HOME%\Scripts\tox +on_failure: + - ps: dir "env:" + - ps: get-content .tox\*\log\* + +### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): +# on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..5ccea46 --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,24 @@ +[bumpversion] +current_version = 0.1.0 +commit = True +tag = True + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file (badge):README.rst] +search = /v{current_version}.svg +replace = /v{new_version}.svg + +[bumpversion:file (link):README.rst] +search = /v{current_version}...main +replace = /v{new_version}...main + +[bumpversion:file:docs/conf.py] +search = version = release = '{current_version}' +replace = version = release = '{new_version}' + +[bumpversion:file:src/edify/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' diff --git a/.cookiecutterrc b/.cookiecutterrc new file mode 100644 index 0000000..b797240 --- /dev/null +++ b/.cookiecutterrc @@ -0,0 +1,74 @@ +# This file exists so you can easily regenerate your project. +# +# `cookiepatcher` is a convenient shim around `cookiecutter` +# for regenerating projects (it will generate a .cookiecutterrc +# automatically for any template). To use it: +# +# pip install cookiepatcher +# cookiepatcher gh:ionelmc/cookiecutter-pylibrary edify +# +# See: +# https://pypi.org/project/cookiepatcher +# +# Alternatively, you can run: +# +# cookiecutter --overwrite-if-exists --config-file=edify/.cookiecutterrc gh:ionelmc/cookiecutter-pylibrary + +default_context: + + _extensions: ['jinja2_time.TimeExtension'] + _template: 'gh:ionelmc/cookiecutter-pylibrary' + allow_tests_inside_package: 'no' + appveyor: 'yes' + c_extension_function: 'longest' + c_extension_module: '_edify' + c_extension_optional: 'no' + c_extension_support: 'no' + c_extension_test_pypi: 'no' + c_extension_test_pypi_username: 'luciferreeves' + codacy: 'no' + codacy_projectid: '[Get ID from https://app.codacy.com/gh/luciferreeves/edify/settings]' + codeclimate: 'no' + codecov: 'yes' + command_line_interface: 'no' + command_line_interface_bin_name: 'edify' + coveralls: 'no' + distribution_name: 'edify' + email: '[email protected]' + full_name: 'Bobby' + github_actions: 'yes' + github_actions_osx: 'yes' + github_actions_windows: 'yes' + legacy_python: 'no' + license: 'Apache Software License 2.0' + linter: 'flake8' + package_name: 'edify' + pre_commit: 'yes' + pre_commit_formatter: 'black' + project_name: 'Edify' + project_short_description: 'Regular Expressions Made Simple' + pypi_badge: 'yes' + pypi_disable_upload: 'no' + release_date: 'today' + repo_hosting: 'github.com' + repo_hosting_domain: 'github.com' + repo_main_branch: 'main' + repo_name: 'edify' + repo_username: 'luciferreeves' + requiresio: 'yes' + scrutinizer: 'no' + setup_py_uses_pytest_runner: 'no' + setup_py_uses_setuptools_scm: 'no' + sphinx_docs: 'yes' + sphinx_docs_hosting: 'https://edify.readthedocs.io/' + sphinx_doctest: 'no' + sphinx_theme: 'sphinx-rtd-theme' + test_matrix_configurator: 'no' + test_matrix_separate_coverage: 'no' + travis: 'no' + travis_osx: 'no' + version: '0.1.0' + version_manager: 'bump2version' + website: 'https://thatcomputerscientist.com' + year_from: '2022' + year_to: '2022' diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..b136d66 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,16 @@ +[paths] +source = + src + */site-packages + +[run] +branch = true +source = + edify + tests +parallel = true + +[report] +show_missing = true +precision = 2 +omit = *migrations* diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..586c736 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# see https://editorconfig.org/ +root = true + +[*] +# Use Unix-style newlines for most files (except Windows files, see below). +end_of_line = lf +trim_trailing_whitespace = true +indent_style = space +insert_final_newline = true +indent_size = 4 +charset = utf-8 + +[*.{bat,cmd,ps1}] +end_of_line = crlf + +[*.{yml,yaml}] +indent_size = 2 + +[*.tsv] +indent_style = tab diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml new file mode 100644 index 0000000..88ad0fc --- /dev/null +++ b/.github/workflows/github-actions.yml @@ -0,0 +1,167 @@ +name: build +on: [push, pull_request] +jobs: + test: + name: ${{ matrix.name }} + runs-on: ${{ matrix.os }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' + - name: 'py36 (ubuntu)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36' + os: 'ubuntu-latest' + - name: 'py36 (windows)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36' + os: 'windows-latest' + - name: 'py36 (macos)' + python: '3.6' + toxpython: 'python3.6' + python_arch: 'x64' + tox_env: 'py36' + os: 'macos-latest' + - name: 'py37 (ubuntu)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37' + os: 'ubuntu-latest' + - name: 'py37 (windows)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37' + os: 'windows-latest' + - name: 'py37 (macos)' + python: '3.7' + toxpython: 'python3.7' + python_arch: 'x64' + tox_env: 'py37' + os: 'macos-latest' + - name: 'py38 (ubuntu)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38' + os: 'ubuntu-latest' + - name: 'py38 (windows)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38' + os: 'windows-latest' + - name: 'py38 (macos)' + python: '3.8' + toxpython: 'python3.8' + python_arch: 'x64' + tox_env: 'py38' + os: 'macos-latest' + - name: 'py39 (ubuntu)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39' + os: 'ubuntu-latest' + - name: 'py39 (windows)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39' + os: 'windows-latest' + - name: 'py39 (macos)' + python: '3.9' + toxpython: 'python3.9' + python_arch: 'x64' + tox_env: 'py39' + os: 'macos-latest' + - name: 'py310 (ubuntu)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310' + os: 'ubuntu-latest' + - name: 'py310 (windows)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310' + os: 'windows-latest' + - name: 'py310 (macos)' + python: '3.10' + toxpython: 'python3.10' + python_arch: 'x64' + tox_env: 'py310' + os: 'macos-latest' + - name: 'pypy37 (ubuntu)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37' + os: 'ubuntu-latest' + - name: 'pypy37 (windows)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37' + os: 'windows-latest' + - name: 'pypy37 (macos)' + python: 'pypy-3.7' + toxpython: 'pypy3.7' + python_arch: 'x64' + tox_env: 'pypy37' + os: 'macos-latest' + - name: 'pypy38 (ubuntu)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38' + os: 'ubuntu-latest' + - name: 'pypy38 (windows)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38' + os: 'windows-latest' + - name: 'pypy38 (macos)' + python: 'pypy-3.8' + toxpython: 'pypy3.8' + python_arch: 'x64' + tox_env: 'pypy38' + os: 'macos-latest' + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python }} + architecture: ${{ matrix.python_arch }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off -r ci/requirements.txt + virtualenv --version + pip --version + tox --version + pip list --format=freeze + - name: test + env: + TOXPYTHON: '${{ matrix.toxpython }}' + run: > + tox -e ${{ matrix.tox_env }} -v diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..83a43fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,74 @@ +*.py[cod] +__pycache__ + +# C extensions +*.so + +# Packages +*.egg +*.egg-info +dist +build +eggs +.eggs +parts +bin +var +sdist +wheelhouse +develop-eggs +.installed.cfg +lib +lib64 +venv*/ +pyvenv*/ +pip-wheel-metadata/ + +# Installer logs +pip-log.txt + +# Unit test / coverage reports +.coverage +.tox +.coverage.* +.pytest_cache/ +nosetests.xml +coverage.xml +htmlcov + +# Translations +*.mo + +# Buildout +.mr.developer.cfg + +# IDE project files +.project +.pydevproject +.idea +.vscode +*.iml +*.komodoproject + +# Complexity +output/*.html +output/*/index.html + +# Sphinx +docs/_build + +.DS_Store +*~ +.*.sw[po] +.build +.ve +.env +.cache +.pytest +.benchmarks +.bootstrap +.appveyor.token +*.bak + +# Mypy Cache +.mypy_cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..8b21f59 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,24 @@ +# To install the git pre-commit hook run: +# pre-commit install +# To update the pre-commit hooks run: +# pre-commit install-hooks +exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)' +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: master + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: debug-statements + - repo: https://github.com/timothycrosley/isort + rev: master + hooks: + - id: isort + - repo: https://github.com/psf/black + rev: main + hooks: + - id: black + - repo: https://gitlab.com/pycqa/flake8 + rev: master + hooks: + - id: flake8 diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 0000000..59ff5c0 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,10 @@ +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details +version: 2 +sphinx: + configuration: docs/conf.py +formats: all +python: + install: + - requirements: docs/requirements.txt + - method: pip + path: . diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 0000000..d772dad --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,5 @@ + +Authors +======= + +* Bobby - https://thatcomputerscientist.com diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..5488144 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,8 @@ + +Changelog +========= + +0.1.0 (2022-08-30) +------------------ + +* First release on PyPI. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..4554597 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,87 @@ +============ +Contributing +============ + +Contributions are welcome, and they are greatly appreciated! Every +little bit helps, and credit will always be given. + +Bug reports +=========== + +When `reporting a bug <https://github.com/luciferreeves/edify/issues>`_ please include: + + * Your operating system name and version. + * Any details about your local setup that might be helpful in troubleshooting. + * Detailed steps to reproduce the bug. + +Documentation improvements +========================== + +Edify could always use more documentation, whether as part of the +official Edify docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Feature requests and feedback +============================= + +The best way to send feedback is to file an issue at https://github.com/luciferreeves/edify/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that code contributions are welcome :) + +Development +=========== + +To set up `edify` for local development: + +1. Fork `edify <https://github.com/luciferreeves/edify>`_ + (look for the "Fork" button). +2. Clone your fork locally:: + + git clone [email protected]:YOURGITHUBNAME/edify.git + +3. Create a branch for local development:: + + git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +4. When you're done making changes run all the checks and docs builder with `tox <https://tox.readthedocs.io/en/latest/install.html>`_ one command:: + + tox + +5. Commit your changes and push your branch to GitHub:: + + git add . + git commit -m "Your detailed description of your changes." + git push origin name-of-your-bugfix-or-feature + +6. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +If you need some code review or feedback while you're developing the code just make the pull request. + +For merging, you should: + +1. Include passing tests (run ``tox``). +2. Update documentation when there's new API, functionality etc. +3. Add a note to ``CHANGELOG.rst`` about the changes. +4. Add yourself to ``AUTHORS.rst``. + + + +Tips +---- + +To run a subset of tests:: + + tox -e envname -- pytest -k test_myfeature + +To run all the test environments in *parallel*:: + + tox -p auto @@ -0,0 +1,15 @@ +Apache Software License 2.0 + +Copyright (c) 2022, Bobby. + +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.
\ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 0000000..de8d247 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,23 @@ +graft docs +graft src +graft ci +graft tests + +include .appveyor.yml +include .bumpversion.cfg +include .cookiecutterrc +include .coveragerc +include .editorconfig +include .github/workflows/github-actions.yml +include .pre-commit-config.yaml +include .readthedocs.yml +include pytest.ini +include tox.ini + +include AUTHORS.rst +include CHANGELOG.rst +include CONTRIBUTING.rst +include LICENSE +include README.rst + +global-exclude *.py[cod] __pycache__/* *.so *.dylib diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..a400fe1 --- /dev/null +++ b/README.rst @@ -0,0 +1,107 @@ +======== +Overview +======== + +.. start-badges + +.. list-table:: + :stub-columns: 1 + + * - docs + - |docs| + * - tests + - | |github-actions| |appveyor| |requires| + | |codecov| + * - package + - | |version| |wheel| |supported-versions| |supported-implementations| + | |commits-since| +.. |docs| image:: https://readthedocs.org/projects/edify/badge/?style=flat + :target: https://edify.readthedocs.io/ + :alt: Documentation Status + +.. |appveyor| image:: https://ci.appveyor.com/api/projects/status/github/luciferreeves/edify?branch=main&svg=true + :alt: AppVeyor Build Status + :target: https://ci.appveyor.com/project/luciferreeves/edify + +.. |github-actions| image:: https://github.com/luciferreeves/edify/actions/workflows/github-actions.yml/badge.svg + :alt: GitHub Actions Build Status + :target: https://github.com/luciferreeves/edify/actions + +.. |requires| image:: https://requires.io/github/luciferreeves/edify/requirements.svg?branch=main + :alt: Requirements Status + :target: https://requires.io/github/luciferreeves/edify/requirements/?branch=main + +.. |codecov| image:: https://codecov.io/gh/luciferreeves/edify/branch/main/graphs/badge.svg?branch=main + :alt: Coverage Status + :target: https://codecov.io/github/luciferreeves/edify + +.. |version| image:: https://img.shields.io/pypi/v/edify.svg + :alt: PyPI Package latest release + :target: https://pypi.org/project/edify + +.. |wheel| image:: https://img.shields.io/pypi/wheel/edify.svg + :alt: PyPI Wheel + :target: https://pypi.org/project/edify + +.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/edify.svg + :alt: Supported versions + :target: https://pypi.org/project/edify + +.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/edify.svg + :alt: Supported implementations + :target: https://pypi.org/project/edify + +.. |commits-since| image:: https://img.shields.io/github/commits-since/luciferreeves/edify/v0.1.0.svg + :alt: Commits since latest release + :target: https://github.com/luciferreeves/edify/compare/v0.1.0...main + + + +.. end-badges + +Regular Expressions Made Simple + +* Free software: Apache Software License 2.0 + +Installation +============ + +:: + + pip install edify + +You can also install the in-development version with:: + + pip install https://github.com/luciferreeves/edify/archive/main.zip + + +Documentation +============= + + +https://edify.readthedocs.io/ + + +Development +=========== + +To run all the tests run:: + + tox + +Note, to combine the coverage data from all the tox environments run: + +.. list-table:: + :widths: 10 90 + :stub-columns: 1 + + - - Windows + - :: + + set PYTEST_ADDOPTS=--cov-append + tox + + - - Other + - :: + + PYTEST_ADDOPTS=--cov-append tox diff --git a/ci/bootstrap.py b/ci/bootstrap.py new file mode 100755 index 0000000..3ca06b7 --- /dev/null +++ b/ci/bootstrap.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +from __future__ import absolute_import +from __future__ import print_function +from __future__ import unicode_literals + +import os +import subprocess +import sys +from os.path import abspath +from os.path import dirname +from os.path import exists +from os.path import join +from os.path import relpath + +base_path = dirname(dirname(abspath(__file__))) +templates_path = join(base_path, "ci", "templates") + + +def check_call(args): + print("+", *args) + subprocess.check_call(args) + + +def exec_in_env(): + env_path = join(base_path, ".tox", "bootstrap") + if sys.platform == "win32": + bin_path = join(env_path, "Scripts") + else: + bin_path = join(env_path, "bin") + if not exists(env_path): + import subprocess + + print("Making bootstrap env in: {0} ...".format(env_path)) + try: + check_call([sys.executable, "-m", "venv", env_path]) + except subprocess.CalledProcessError: + try: + check_call([sys.executable, "-m", "virtualenv", env_path]) + except subprocess.CalledProcessError: + check_call(["virtualenv", env_path]) + print("Installing `jinja2` into bootstrap environment...") + check_call([join(bin_path, "pip"), "install", "jinja2", "tox"]) + python_executable = join(bin_path, "python") + if not os.path.exists(python_executable): + python_executable += '.exe' + + print("Re-executing with: {0}".format(python_executable)) + print("+ exec", python_executable, __file__, "--no-env") + os.execv(python_executable, [python_executable, __file__, "--no-env"]) + + +def main(): + import jinja2 + + print("Project path: {0}".format(base_path)) + + jinja = jinja2.Environment( + loader=jinja2.FileSystemLoader(templates_path), + trim_blocks=True, + lstrip_blocks=True, + keep_trailing_newline=True, + ) + + tox_environments = [ + line.strip() + # 'tox' need not be installed globally, but must be importable + # by the Python that is running this script. + # This uses sys.executable the same way that the call in + # cookiecutter-pylibrary/hooks/post_gen_project.py + # invokes this bootstrap.py itself. + for line in subprocess.check_output([sys.executable, '-m', 'tox', '--listenvs'], universal_newlines=True).splitlines() + ] + tox_environments = [line for line in tox_environments if line.startswith('py')] + + for root, _, files in os.walk(templates_path): + for name in files: + relative = relpath(root, templates_path) + with open(join(base_path, relative, name), "w") as fh: + fh.write(jinja.get_template(join(relative, name)).render(tox_environments=tox_environments)) + print("Wrote {}".format(name)) + print("DONE.") + + +if __name__ == "__main__": + args = sys.argv[1:] + if args == ["--no-env"]: + main() + elif not args: + exec_in_env() + else: + print("Unexpected arguments {0}".format(args), file=sys.stderr) + sys.exit(1) diff --git a/ci/requirements.txt b/ci/requirements.txt new file mode 100644 index 0000000..a0ef106 --- /dev/null +++ b/ci/requirements.txt @@ -0,0 +1,5 @@ +virtualenv>=16.6.0 +pip>=19.1.1 +setuptools>=18.0.1 +six>=1.14.0 +tox diff --git a/ci/templates/.appveyor.yml b/ci/templates/.appveyor.yml new file mode 100644 index 0000000..a64923b --- /dev/null +++ b/ci/templates/.appveyor.yml @@ -0,0 +1,46 @@ +version: '{branch}-{build}' +build: off +image: Visual Studio 2019 +environment: + matrix: + - TOXENV: check + TOXPYTHON: C:\Python36\python.exe + PYTHON_HOME: C:\Python36 + PYTHON_VERSION: '3.6' + PYTHON_ARCH: '32' +{% for env in tox_environments %} +{% if env.startswith(('py2', 'py3')) %} + - TOXENV: {{ env }},codecov{{ "" }} + TOXPYTHON: C:\Python{{ env[2:4] }}\python.exe + PYTHON_HOME: C:\Python{{ env[2:4] }} + PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' + PYTHON_ARCH: '32' +{% if 'nocov' in env %} + WHEEL_PATH: .tox/dist +{% endif %} + - TOXENV: {{ env }},codecov{{ "" }} + TOXPYTHON: C:\Python{{ env[2:4] }}-x64\python.exe + PYTHON_HOME: C:\Python{{ env[2:4] }}-x64 + PYTHON_VERSION: '{{ env[2] }}.{{ env[3] }}' + PYTHON_ARCH: '64' +{% if 'nocov' in env %} + WHEEL_PATH: .tox/dist +{% endif %} +{% endif %}{% endfor %} +init: + - ps: echo $env:TOXENV + - ps: ls C:\Python* +install: + - '%PYTHON_HOME%\python -mpip install --progress-bar=off tox -rci/requirements.txt' + - '%PYTHON_HOME%\Scripts\virtualenv --version' + - '%PYTHON_HOME%\Scripts\pip --version' + - '%PYTHON_HOME%\Scripts\tox --version' +test_script: + - %PYTHON_HOME%\Scripts\tox +on_failure: + - ps: dir "env:" + - ps: get-content .tox\*\log\* + +### To enable remote debugging uncomment this (also, see: http://www.appveyor.com/docs/how-to/rdp-to-build-worker): +# on_finish: +# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) diff --git a/ci/templates/.github/workflows/github-actions.yml b/ci/templates/.github/workflows/github-actions.yml new file mode 100644 index 0000000..7ee6426 --- /dev/null +++ b/ci/templates/.github/workflows/github-actions.yml @@ -0,0 +1,65 @@ +name: build +on: [push, pull_request] +jobs: + test: + name: {{ '${{ matrix.name }}' }} + runs-on: {{ '${{ matrix.os }}' }} + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + include: + - name: 'check' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'check' + os: 'ubuntu-latest' + - name: 'docs' + python: '3.9' + toxpython: 'python3.9' + tox_env: 'docs' + os: 'ubuntu-latest' +{% for env in tox_environments %} +{% set prefix = env.split('-')[0] -%} +{% if prefix.startswith('pypy') %} +{% set python %}pypy-{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% set cpython %}pp{{ prefix[4:5] }}{% endset %} +{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5] }}{% endset %} +{% else %} +{% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% set cpython %}cp{{ prefix[2:] }}{% endset %} +{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{% endset %} +{% endif %} +{% for os, python_arch in [ + ['ubuntu', 'x64'], + ['windows', 'x64'], + ['macos', 'x64'], +] %} + - name: '{{ env }} ({{ os }})' + python: '{{ python }}' + toxpython: '{{ toxpython }}' + python_arch: '{{ python_arch }}' + tox_env: '{{ env }}{% if 'cover' in env %},codecov{% endif %}' + os: '{{ os }}-latest' +{% endfor %} +{% endfor %} + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + - uses: actions/setup-python@v2 + with: + python-version: {{ '${{ matrix.python }}' }} + architecture: {{ '${{ matrix.python_arch }}' }} + - name: install dependencies + run: | + python -mpip install --progress-bar=off -r ci/requirements.txt + virtualenv --version + pip --version + tox --version + pip list --format=freeze + - name: test + env: + TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}' + run: > + tox -e {{ '${{ matrix.tox_env }}' }} -v diff --git a/docs/authors.rst b/docs/authors.rst new file mode 100644 index 0000000..e122f91 --- /dev/null +++ b/docs/authors.rst @@ -0,0 +1 @@ +.. include:: ../AUTHORS.rst diff --git a/docs/changelog.rst b/docs/changelog.rst new file mode 100644 index 0000000..565b052 --- /dev/null +++ b/docs/changelog.rst @@ -0,0 +1 @@ +.. include:: ../CHANGELOG.rst diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..7a37755 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +import os + +extensions = [ + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.coverage', + 'sphinx.ext.doctest', + 'sphinx.ext.extlinks', + 'sphinx.ext.ifconfig', + 'sphinx.ext.napoleon', + 'sphinx.ext.todo', + 'sphinx.ext.viewcode', +] +source_suffix = '.rst' +master_doc = 'index' +project = 'Edify' +year = '2022' +author = 'Bobby' +copyright = '{0}, {1}'.format(year, author) +version = release = '0.1.0' + +pygments_style = 'trac' +templates_path = ['.'] +extlinks = { + 'issue': ('https://github.com/luciferreeves/edify/issues/%s', '#'), + 'pr': ('https://github.com/luciferreeves/edify/pull/%s', 'PR #'), +} +# on_rtd is whether we are on readthedocs.org +on_rtd = os.environ.get('READTHEDOCS', None) == 'True' + +if not on_rtd: # only set the theme if we're building docs locally + html_theme = 'sphinx_rtd_theme' + +html_use_smartypants = True +html_last_updated_fmt = '%b %d, %Y' +html_split_index = False +html_sidebars = { + '**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'], +} +html_short_title = '%s-%s' % (project, version) + +napoleon_use_ivar = True +napoleon_use_rtype = False +napoleon_use_param = False diff --git a/docs/contributing.rst b/docs/contributing.rst new file mode 100644 index 0000000..e582053 --- /dev/null +++ b/docs/contributing.rst @@ -0,0 +1 @@ +.. include:: ../CONTRIBUTING.rst diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..ad842d5 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,21 @@ +======== +Contents +======== + +.. toctree:: + :maxdepth: 2 + + readme + installation + usage + reference/index + contributing + authors + changelog + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/installation.rst b/docs/installation.rst new file mode 100644 index 0000000..1fb9d10 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,7 @@ +============ +Installation +============ + +At the command line:: + + pip install edify diff --git a/docs/readme.rst b/docs/readme.rst new file mode 100644 index 0000000..72a3355 --- /dev/null +++ b/docs/readme.rst @@ -0,0 +1 @@ +.. include:: ../README.rst diff --git a/docs/reference/edify.rst b/docs/reference/edify.rst new file mode 100644 index 0000000..6374fd4 --- /dev/null +++ b/docs/reference/edify.rst @@ -0,0 +1,9 @@ +edify +===== + +.. testsetup:: + + from edify import * + +.. automodule:: edify + :members: diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 0000000..df7e04e --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,7 @@ +Reference +========= + +.. toctree:: + :glob: + + edify* diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..37da9ae --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,2 @@ +sphinx>=1.3 +sphinx-rtd-theme diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt new file mode 100644 index 0000000..f95eb78 --- /dev/null +++ b/docs/spelling_wordlist.txt @@ -0,0 +1,11 @@ +builtin +builtins +classmethod +staticmethod +classmethods +staticmethods +args +kwargs +callstack +Changelog +Indices diff --git a/docs/usage.rst b/docs/usage.rst new file mode 100644 index 0000000..7cce1cb --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,7 @@ +===== +Usage +===== + +To use Edify in a project:: + + import edify diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..a51acf9 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,10 @@ +[build-system] +requires = [ + "setuptools>=30.3.0", + "wheel", +] + +[tool.black] +line-length = 140 +target-version = ['py36'] +skip-string-normalization = true diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..d604d65 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,28 @@ +[pytest] +# If a pytest section is found in one of the possible config files +# (pytest.ini, tox.ini or setup.cfg), then pytest will not look for any others, +# so if you add a pytest config section elsewhere, +# you will need to delete this section from setup.cfg. +norecursedirs = + migrations + +python_files = + test_*.py + *_test.py + tests.py +addopts = + -ra + --strict-markers + --doctest-modules + --doctest-glob=\*.rst + --tb=short +testpaths = + tests + +# Idea from: https://til.simonwillison.net/pytest/treat-warnings-as-errors +filterwarnings = + error +# You can add exclusions, some examples: +# ignore:'edify' defines default_app_config:PendingDeprecationWarning:: +# ignore:The {{% if::: +# ignore:Coverage disabled via --no-cov switch! diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..cc23bcc --- /dev/null +++ b/setup.cfg @@ -0,0 +1,11 @@ +[flake8] +max-line-length = 140 +exclude = .tox,.eggs,ci/templates,build,dist + +[tool:isort] +force_single_line = True +line_length = 120 +known_first_party = edify +default_section = THIRDPARTY +forced_separate = test_edify +skip = .tox,.eggs,ci/templates,build,dist diff --git a/setup.py b/setup.py new file mode 100755 index 0000000..7750988 --- /dev/null +++ b/setup.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- + +import io +import re +from glob import glob +from os.path import basename +from os.path import dirname +from os.path import join +from os.path import splitext + +from setuptools import find_packages +from setuptools import setup + + +def read(*names, **kwargs): + with io.open(join(dirname(__file__), *names), encoding=kwargs.get('encoding', 'utf8')) as fh: + return fh.read() + + +setup( + name='edify', + version='0.1.0', + license='Apache-2.0', + description='Regular Expressions Made Simple', + long_description='{}\n{}'.format( + re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), + re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')), + ), + author='Bobby', + author_email='[email protected]', + url='https://github.com/luciferreeves/edify', + packages=find_packages('src'), + package_dir={'': 'src'}, + py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')], + include_package_data=True, + zip_safe=False, + classifiers=[ + # complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers + 'Development Status :: 5 - Production/Stable', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Apache Software License', + 'Operating System :: Unix', + 'Operating System :: POSIX', + 'Operating System :: Microsoft :: Windows', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3 :: Only', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: Implementation :: CPython', + 'Programming Language :: Python :: Implementation :: PyPy', + # uncomment if you test on these interpreters: + # 'Programming Language :: Python :: Implementation :: IronPython', + # 'Programming Language :: Python :: Implementation :: Jython', + # 'Programming Language :: Python :: Implementation :: Stackless', + 'Topic :: Utilities', + ], + project_urls={ + 'Documentation': 'https://edify.readthedocs.io/', + 'Changelog': 'https://edify.readthedocs.io/en/latest/changelog.html', + 'Issue Tracker': 'https://github.com/luciferreeves/edify/issues', + }, + keywords=[ + # eg: 'keyword1', 'keyword2', 'keyword3', + ], + python_requires='>=3.6', + install_requires=[ + # eg: 'aspectlib==1.1.1', 'six>=1.7', + ], + extras_require={ + # eg: + # 'rst': ['docutils>=0.11'], + # ':python_version=="2.6"': ['argparse'], + }, +) diff --git a/src/edify/__init__.py b/src/edify/__init__.py new file mode 100644 index 0000000..b794fd4 --- /dev/null +++ b/src/edify/__init__.py @@ -0,0 +1 @@ +__version__ = '0.1.0' diff --git a/tests/test_edify.py b/tests/test_edify.py new file mode 100644 index 0000000..0aea1ab --- /dev/null +++ b/tests/test_edify.py @@ -0,0 +1,6 @@ + +from edify import main + + +def test_main(): + pass @@ -0,0 +1,85 @@ +[testenv:bootstrap] +deps = + jinja2 + tox +skip_install = true +commands = + python ci/bootstrap.py --no-env +passenv = + * +; a generative tox configuration, see: https://tox.readthedocs.io/en/latest/config.html#generative-envlist + +[tox] +envlist = + clean, + check, + docs, + {py36,py37,py38,py39,py310,pypy37,pypy38}, + report +ignore_basepython_conflict = true + +[testenv] +basepython = + pypy37: {env:TOXPYTHON:pypy3.7} + pypy38: {env:TOXPYTHON:pypy3.8} + py36: {env:TOXPYTHON:python3.6} + py37: {env:TOXPYTHON:python3.7} + py38: {env:TOXPYTHON:python3.8} + py39: {env:TOXPYTHON:python3.9} + py310: {env:TOXPYTHON:python3.10} + {bootstrap,clean,check,report,docs,codecov}: {env:TOXPYTHON:python3} +setenv = + PYTHONPATH={toxinidir}/tests + PYTHONUNBUFFERED=yes +passenv = + * +usedevelop = false +deps = + pytest + pytest-cov +commands = + {posargs:pytest --cov --cov-report=term-missing -vv tests} + +[testenv:check] +deps = + docutils + check-manifest + flake8 + readme-renderer + pygments + isort +skip_install = true +commands = + python setup.py check --strict --metadata --restructuredtext + check-manifest {toxinidir} + flake8 + isort --verbose --check-only --diff --filter-files . + +[testenv:docs] +usedevelop = true +deps = + -r{toxinidir}/docs/requirements.txt +commands = + sphinx-build {posargs:-E} -b html docs dist/docs + sphinx-build -b linkcheck docs dist/docs + +[testenv:codecov] +deps = + codecov +skip_install = true +commands = + codecov [] + +[testenv:report] +deps = + coverage +skip_install = true +commands = + coverage report + coverage html + +[testenv:clean] +commands = coverage erase +skip_install = true +deps = + coverage |
