diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..fd5950d --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,20 @@ +[bumpversion] +current_version = 0.0.1 +commit = True +tag = True + +[bumpversion:file:setup.py] +search = version='{current_version}' +replace = version='{new_version}' + +[bumpversion:file:README.rst] +search = v{current_version}. +replace = v{new_version}. + +[bumpversion:file:docs/conf.py] +search = version = release = '{current_version}' +replace = version = release = '{new_version}' + +[bumpversion:file:src/averell/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' diff --git a/.cookiecutterrc b/.cookiecutterrc new file mode 100644 index 0000000..ca609e6 --- /dev/null +++ b/.cookiecutterrc @@ -0,0 +1,69 @@ +# 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 project-path +# +# See: +# https://pypi.org/project/cookiepatcher +# +# Alternatively, you can run: +# +# cookiecutter --overwrite-if-exists --config-file=project-path/.cookiecutterrc gh:ionelmc/cookiecutter-pylibrary + +default_context: + + _extensions: ['jinja2_time.TimeExtension'] + _template: 'gh:ionelmc/cookiecutter-pylibrary' + allow_tests_inside_package: 'no' + appveyor: 'no' + c_extension_function: 'longest' + c_extension_module: '_averell' + c_extension_optional: 'no' + c_extension_support: 'no' + c_extension_test_pypi: 'no' + c_extension_test_pypi_username: 'linhd-postdata' + codacy: 'no' + codacy_projectid: '[Get ID from https://app.codacy.com/app/linhd-postdata/averell/settings]' + codeclimate: 'no' + codecov: 'yes' + command_line_interface: 'click' + command_line_interface_bin_name: 'averell' + coveralls: 'no' + coveralls_token: '[Required for Appveyor, take it from https://coveralls.io/github/linhd-postdata/averell]' + distribution_name: 'averell' + email: 'info@linhd.uned.es' + full_name: 'LINHD POSTDATA Project' + landscape: 'yes' + license: 'Apache Software License 2.0' + linter: 'flake8' + package_name: 'averell' + project_name: 'averell' + project_short_description: 'Corpora downloader and reader for Spanish sources' + pypi_badge: 'yes' + pypi_disable_upload: 'no' + release_date: 'today' + repo_hosting: 'github.com' + repo_hosting_domain: 'github.com' + repo_name: 'averell' + repo_username: 'linhd-postdata' + requiresio: 'no' + scrutinizer: 'no' + setup_py_uses_setuptools_scm: 'no' + setup_py_uses_test_runner: 'yes' + sphinx_docs: 'yes' + sphinx_docs_hosting: 'https://averell.readthedocs.io/' + sphinx_doctest: 'no' + sphinx_theme: 'sphinx-rtd-theme' + test_matrix_configurator: 'yes' + test_matrix_separate_coverage: 'no' + test_runner: 'pytest' + travis: 'yes' + travis_osx: 'no' + version: '0.0.1' + website: 'https://github.com/linhd-postdata/averell' + year_from: '2019' + year_to: '2020' diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..412759d --- /dev/null +++ b/.coveragerc @@ -0,0 +1,16 @@ +[paths] +source = + src + */site-packages + +[run] +branch = true +source = + averell + tests +parallel = true + +[report] +show_missing = true +precision = 2 +omit = *migrations* diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6eb7567 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +# see https://editorconfig.org/ +root = true + +[*] +end_of_line = lf +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 4 +charset = utf-8 + +[*.{bat,cmd,ps1}] +end_of_line = crlf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..dfe5838 --- /dev/null +++ b/.gitignore @@ -0,0 +1,71 @@ +*.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 + +# Mr Developer +.mr.developer.cfg +.project +.pydevproject +.idea +*.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/.travis.yml b/.travis.yml new file mode 100644 index 0000000..4782428 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,56 @@ +language: python +dist: xenial +cache: false +env: + global: + - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + - SEGFAULT_SIGNALS=all +matrix: + include: + - python: '3.6' + env: + - TOXENV=check + - python: '3.6' + env: + - TOXENV=docs + - env: + - TOXENV=py27 + python: '2.7' + - env: + - TOXENV=py35 + python: '3.5' + - env: + - TOXENV=py36 + python: '3.6' + - env: + - TOXENV=py37 + python: '3.7' + - env: + - TOXENV=py38 + python: '3.8' + - env: + - TOXENV=pypy + python: 'pypy' + - env: + - TOXENV=pypy3 + - TOXPYTHON=pypy3 + python: 'pypy3' +before_install: + - python --version + - uname -a + - lsb_release -a || true +install: + - python -mpip install --progress-bar=off tox -rci/requirements.txt + - virtualenv --version + - easy_install --version + - pip --version + - tox --version +script: + - tox -v +after_failure: + - more .tox/log/* | cat + - more .tox/*/log/* | cat +notifications: + email: + on_success: never + on_failure: always diff --git a/AUTHORS.rst b/AUTHORS.rst new file mode 100644 index 0000000..c2b9e9f --- /dev/null +++ b/AUTHORS.rst @@ -0,0 +1,5 @@ + +Authors +======= + +* LINHD POSTDATA Project - https://github.com/linhd-postdata/averell diff --git a/CHANGELOG.rst b/CHANGELOG.rst new file mode 100644 index 0000000..bfe69c5 --- /dev/null +++ b/CHANGELOG.rst @@ -0,0 +1,8 @@ + +Changelog +========= + +0.0.1 (2020-01-08) +------------------ + +* First release on PyPI. diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..41bded3 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,90 @@ +============ +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 `_ 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 +========================== + +averell could always use more documentation, whether as part of the +official averell 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/linhd-postdata/averell/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 `averell` for local development: + +1. Fork `averell `_ + (look for the "Fork" button). +2. Clone your fork locally:: + + git clone git@github.com:linhd-postdata/averell.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 `_ 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``) [1]_. +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``. + +.. [1] If you don't have all the necessary python versions available locally you can rely on Travis - it will + `run the tests `_ for each change you add in the pull request. + + It will be slower though ... + +Tips +---- + +To run a subset of tests:: + + tox -e envname -- pytest -k test_myfeature + +To run all the test environments in *parallel* (you need to ``pip install detox``):: + + detox diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1379b5c --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +Apache Software License 2.0 + +Copyright (c) 2019-2020, LINHD POSTDATA Project. + +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..6e304e1 --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,19 @@ +graft docs +graft src +graft ci +graft tests + +include .bumpversion.cfg +include .coveragerc +include .cookiecutterrc +include .editorconfig + +include AUTHORS.rst +include CHANGELOG.rst +include CONTRIBUTING.rst +include LICENSE +include README.rst + +include tox.ini .travis.yml .appveyor.yml + +global-exclude *.py[cod] __pycache__/* *.so *.dylib diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..1a1f207 --- /dev/null +++ b/README.rst @@ -0,0 +1,104 @@ +======== +Overview +======== + +.. start-badges + +.. list-table:: + :stub-columns: 1 + + * - docs + - |docs| + * - tests + - | |travis| + | |codecov| + | |landscape| + * - package + - | |version| |wheel| |supported-versions| |supported-implementations| + | |commits-since| +.. |docs| image:: https://readthedocs.org/projects/averell/badge/?style=flat + :target: https://readthedocs.org/projects/averell + :alt: Documentation Status + +.. |travis| image:: https://api.travis-ci.org/linhd-postdata/averell.svg?branch=master + :alt: Travis-CI Build Status + :target: https://travis-ci.org/linhd-postdata/averell + +.. |codecov| image:: https://codecov.io/github/linhd-postdata/averell/coverage.svg?branch=master + :alt: Coverage Status + :target: https://codecov.io/github/linhd-postdata/averell + +.. |landscape| image:: https://landscape.io/github/linhd-postdata/averell/master/landscape.svg?style=flat + :target: https://landscape.io/github/linhd-postdata/averell/master + :alt: Code Quality Status + +.. |version| image:: https://img.shields.io/pypi/v/averell.svg + :alt: PyPI Package latest release + :target: https://pypi.org/project/averell + +.. |wheel| image:: https://img.shields.io/pypi/wheel/averell.svg + :alt: PyPI Wheel + :target: https://pypi.org/project/averell + +.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/averell.svg + :alt: Supported versions + :target: https://pypi.org/project/averell + +.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/averell.svg + :alt: Supported implementations + :target: https://pypi.org/project/averell + +.. |commits-since| image:: https://img.shields.io/github/commits-since/linhd-postdata/averell/v0.0.1.svg + :alt: Commits since latest release + :target: https://github.com/linhd-postdata/averell/compare/v0.0.1...master + + + +.. end-badges + +Corpora downloader and reader for Spanish sources + +* Free software: Apache Software License 2.0 + +Installation +============ + +:: + + pip install averell + +You can also install the in-development version with:: + + pip install https://github.com/linhd-postdata/averell/archive/master.zip + + +Documentation +============= + + +https://averell.readthedocs.io/ + + +Development +=========== + +To run the all 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..2d14d54 --- /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 sys +from os.path import abspath +from os.path import dirname +from os.path import exists +from os.path import join + +base_path = dirname(dirname(abspath(__file__))) + + +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", "matrix"]) + 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 + import matrix + + + print("Project path: {0}".format(base_path)) + + jinja = jinja2.Environment( + loader=jinja2.FileSystemLoader(join(base_path, "ci", "templates")), + trim_blocks=True, + lstrip_blocks=True, + keep_trailing_newline=True + ) + + tox_environments = {} + for (alias, conf) in matrix.from_file(join(base_path, "setup.cfg")).items(): + python = conf["python_versions"] + deps = conf["dependencies"] + tox_environments[alias] = { + "deps": deps.split(), + } + if "coverage_flags" in conf: + cover = {"false": False, "true": True}[conf["coverage_flags"].lower()] + tox_environments[alias].update(cover=cover) + if "environment_variables" in conf: + env_vars = conf["environment_variables"] + tox_environments[alias].update(env_vars=env_vars.split()) + + for name in os.listdir(join("ci", "templates")): + with open(join(base_path, name), "w") as fh: + fh.write(jinja.get_template(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..1c8d385 --- /dev/null +++ b/ci/requirements.txt @@ -0,0 +1,3 @@ +virtualenv>=16.6.0 +pip>=19.1.1 +setuptools>=18.0.1 diff --git a/ci/templates/.travis.yml b/ci/templates/.travis.yml new file mode 100644 index 0000000..449ffc2 --- /dev/null +++ b/ci/templates/.travis.yml @@ -0,0 +1,46 @@ +language: python +dist: xenial +cache: false +env: + global: + - LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so + - SEGFAULT_SIGNALS=all +matrix: + include: + - python: '3.6' + env: + - TOXENV=check + - python: '3.6' + env: + - TOXENV=docs +{%- for env, config in tox_environments|dictsort %}{{ '' }} + - env: + - TOXENV={{ env }}{% if config.cover %},codecov{% endif %} +{%- if env.startswith('pypy3') %}{{ '' }} + - TOXPYTHON=pypy3 + python: 'pypy3' +{%- elif env.startswith('pypy') %}{{ '' }} + python: 'pypy' +{%- else %}{{ '' }} + python: '{{ '{0[2]}.{0[3]}'.format(env) }}' +{%- endif %} +{%- endfor %}{{ '' }} +before_install: + - python --version + - uname -a + - lsb_release -a || true +install: + - python -mpip install --progress-bar=off tox -rci/requirements.txt + - virtualenv --version + - easy_install --version + - pip --version + - tox --version +script: + - tox -v +after_failure: + - more .tox/log/* | cat + - more .tox/*/log/* | cat +notifications: + email: + on_success: never + on_failure: always diff --git a/ci/templates/tox.ini b/ci/templates/tox.ini new file mode 100644 index 0000000..29dbcc6 --- /dev/null +++ b/ci/templates/tox.ini @@ -0,0 +1,104 @@ +[tox] +envlist = + clean, + check, + docs, +{% for env in tox_environments|sort %} + {{ env }}, +{% endfor %} + report + +[testenv] +basepython = + docs: {env:TOXPYTHON:python3.6} + {bootstrap,clean,check,report,codecov}: {env:TOXPYTHON:python3} +setenv = + PYTHONPATH={toxinidir}/tests + PYTHONUNBUFFERED=yes +passenv = + * +deps = + pytest + pytest-travis-fold + pytest-cov +commands = + {posargs:pytest --cov --cov-report=term-missing -vv --ignore=src} + +[testenv:bootstrap] +deps = + jinja2 + matrix +skip_install = true +commands = + python ci/bootstrap.py --no-env + +[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 src tests setup.py + isort --verbose --check-only --diff --recursive src tests setup.py + + +[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 +{% for env, config in tox_environments|dictsort %} + +[testenv:{{ env }}] +basepython = {env:TOXPYTHON:{{ env.split("-")[0] if env.startswith("pypy") else "python{0[2]}.{0[3]}".format(env) }}} +{% if config.cover or config.env_vars %} +setenv = + {[testenv]setenv} +{% endif %} +{% for var in config.env_vars %} + {{ var }} +{% endfor %} +{% if config.cover %} +usedevelop = true +commands = + {posargs:pytest --cov --cov-report=term-missing -vv} +{% endif %} +{% if config.cover or config.deps %} +deps = + {[testenv]deps} +{% endif %} +{% if config.cover %} + pytest-cov +{% endif %} +{% for dep in config.deps %} + {{ dep }} +{% endfor -%} +{% endfor -%} 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..74cd2d1 --- /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 = 'averell' +year = '2019-2020' +author = 'LINHD POSTDATA Project' +copyright = '{0}, {1}'.format(year, author) +version = release = '0.0.1' + +pygments_style = 'trac' +templates_path = ['.'] +extlinks = { + 'issue': ('https://github.com/linhd-postdata/averell/issues/%s', '#'), + 'pr': ('https://github.com/linhd-postdata/averell/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..40f35b5 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +======== +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..ffa75d5 --- /dev/null +++ b/docs/installation.rst @@ -0,0 +1,7 @@ +============ +Installation +============ + +At the command line:: + + pip install averell 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/averell.rst b/docs/reference/averell.rst new file mode 100644 index 0000000..c7cb0e8 --- /dev/null +++ b/docs/reference/averell.rst @@ -0,0 +1,9 @@ +averell +======= + +.. testsetup:: + + from averell import * + +.. automodule:: averell + :members: diff --git a/docs/reference/index.rst b/docs/reference/index.rst new file mode 100644 index 0000000..343cba4 --- /dev/null +++ b/docs/reference/index.rst @@ -0,0 +1,7 @@ +Reference +========= + +.. toctree:: + :glob: + + averell* 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..4c39407 --- /dev/null +++ b/docs/usage.rst @@ -0,0 +1,7 @@ +===== +Usage +===== + +To use averell in a project:: + + import averell diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1791e35 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,101 @@ +[bdist_wheel] +universal = 1 + +[flake8] +max-line-length = 140 +exclude = */migrations/* + +[options] +# tests_require is a list of dependencies that are *absolutely required* +# to run the tests. tests_require is used when running tests from your +# *current* Python environment (that is, not using tox). +# tests_require is ignored by tox. +# +# As such, you can usually get away with neglecting tests_require --- +# it's not a big deal if some of the dependencies get left out. +# +# If you're running tests from your current environment, it's because +# you're actively developing, in which case you usually have an +# environment you built for development. But if you have to change +# environments mid-development for any reason, tests_require can save you +# from getting tripped up. +# +# tests_require is used when running tests and debugging through an IDE like +# PyCharm, to ensure the environment the IDE is using has the requirements. +# +# Unless you're in one of those situations, you can simply ignore this. +tests_require = pytest + +[aliases] +# Alias `setup.py test` to `setup.py pytest` +test = pytest + +[tool: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 + --doctest-modules + --doctest-glob=\*.rst + --tb=short +testpaths = + tests + +[tool:isort] +force_single_line = True +line_length = 120 +known_first_party = averell +default_section = THIRDPARTY +forced_separate = test_averell +not_skip = __init__.py +skip = migrations + +[matrix] +# This is the configuration for the `./bootstrap.py` script. +# It generates `.travis.yml`, `tox.ini` and `.appveyor.yml`. +# +# Syntax: [alias:] value [!variable[glob]] [&variable[glob]] +# +# alias: +# - is used to generate the tox environment +# - it's optional +# - if not present the alias will be computed from the `value` +# value: +# - a value of "-" means empty +# !variable[glob]: +# - exclude the combination of the current `value` with +# any value matching the `glob` in `variable` +# - can use as many you want +# &variable[glob]: +# - only include the combination of the current `value` +# when there's a value matching `glob` in `variable` +# - can use as many you want + +python_versions = + py27 + py35 + py36 + py37 + py38 + pypy + pypy3 + +dependencies = +# 1.4: Django==1.4.16 !python_versions[py3*] +# 1.5: Django==1.5.11 +# 1.6: Django==1.6.8 +# 1.7: Django==1.7.1 !python_versions[py26] +# Deps commented above are provided as examples. That's what you would use in a Django project. + +environment_variables = + - diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..1a01999 --- /dev/null +++ b/setup.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +from __future__ import absolute_import +from __future__ import print_function + +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='averell', + version='0.0.1', + license='Apache-2.0', + description='Corpora downloader and reader for Spanish sources', + long_description='%s\n%s' % ( + re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')), + re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst')) + ), + author='LINHD POSTDATA Project', + author_email='info@linhd.uned.es', + url='https://github.com/linhd-postdata/averell', + 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 :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + '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://averell.readthedocs.io/', + 'Changelog': 'https://averell.readthedocs.io/en/latest/changelog.html', + 'Issue Tracker': 'https://github.com/linhd-postdata/averell/issues', + }, + keywords=[ + # eg: 'keyword1', 'keyword2', 'keyword3', + ], + python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*', + install_requires=[ + 'click', + # eg: 'aspectlib==1.1.1', 'six>=1.7', + ], + extras_require={ + # eg: + # 'rst': ['docutils>=0.11'], + # ':python_version=="2.6"': ['argparse'], + }, + setup_requires=[ + 'pytest-runner', + ], + entry_points={ + 'console_scripts': [ + 'averell = averell.cli:main', + ] + }, +) diff --git a/src/averell/__init__.py b/src/averell/__init__.py new file mode 100644 index 0000000..b8023d8 --- /dev/null +++ b/src/averell/__init__.py @@ -0,0 +1 @@ +__version__ = '0.0.1' diff --git a/src/averell/__main__.py b/src/averell/__main__.py new file mode 100644 index 0000000..abf7b01 --- /dev/null +++ b/src/averell/__main__.py @@ -0,0 +1,14 @@ +""" +Entrypoint module, in case you use `python -maverell`. + + +Why does this file exist, and why __main__? For more info, read: + +- https://www.python.org/dev/peps/pep-0338/ +- https://docs.python.org/2/using/cmdline.html#cmdoption-m +- https://docs.python.org/3/using/cmdline.html#cmdoption-m +""" +from averell.cli import main + +if __name__ == "__main__": + main() diff --git a/src/averell/cli.py b/src/averell/cli.py new file mode 100644 index 0000000..4403e04 --- /dev/null +++ b/src/averell/cli.py @@ -0,0 +1,23 @@ +""" +Module that contains the command line app. + +Why does this file exist, and why not put this in __main__? + + You might be tempted to import things from __main__ later, but that will cause + problems: the code will get executed twice: + + - When you run `python -maverell` python will execute + ``__main__.py`` as a script. That means there won't be any + ``averell.__main__`` in ``sys.modules``. + - When you import __main__ it will get executed again (as a module) because + there's no ``averell.__main__`` in ``sys.modules``. + + Also see (1) from http://click.pocoo.org/5/setuptools/#setuptools-integration +""" +import click + + +@click.command() +@click.argument('names', nargs=-1) +def main(names): + click.echo(repr(names)) diff --git a/tests/test_averell.py b/tests/test_averell.py new file mode 100644 index 0000000..03f4daa --- /dev/null +++ b/tests/test_averell.py @@ -0,0 +1,12 @@ + +from click.testing import CliRunner + +from averell.cli import main + + +def test_main(): + runner = CliRunner() + result = runner.invoke(main, []) + + assert result.output == '()\n' + assert result.exit_code == 0 diff --git a/tox.ini b/tox.ini new file mode 100644 index 0000000..6cacb3d --- /dev/null +++ b/tox.ini @@ -0,0 +1,102 @@ +[tox] +envlist = + clean, + check, + docs, + py27, + py35, + py36, + py37, + py38, + pypy, + pypy3, + report + +[testenv] +basepython = + docs: {env:TOXPYTHON:python3.6} + {bootstrap,clean,check,report,codecov}: {env:TOXPYTHON:python3} +setenv = + PYTHONPATH={toxinidir}/tests + PYTHONUNBUFFERED=yes +passenv = + * +deps = + pytest + pytest-travis-fold + pytest-cov +commands = + {posargs:pytest --cov --cov-report=term-missing -vv --ignore=src} + +[testenv:bootstrap] +deps = + jinja2 + matrix +skip_install = true +commands = + python ci/bootstrap.py --no-env + +[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 src tests setup.py + isort --verbose --check-only --diff --recursive src tests setup.py + + +[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 + +[testenv:py27] +basepython = {env:TOXPYTHON:python2.7} + +[testenv:py35] +basepython = {env:TOXPYTHON:python3.5} + +[testenv:py36] +basepython = {env:TOXPYTHON:python3.6} + +[testenv:py37] +basepython = {env:TOXPYTHON:python3.7} + +[testenv:py38] +basepython = {env:TOXPYTHON:python3.8} + +[testenv:pypy] +basepython = {env:TOXPYTHON:pypy} + +[testenv:pypy3] +basepython = {env:TOXPYTHON:pypy3}