From 7d0d35080b32dc9a3b47f371db47fe215e53e039 Mon Sep 17 00:00:00 2001 From: chfw Date: Tue, 13 Oct 2020 21:31:23 +0100 Subject: [PATCH] :handshake: demo 2: a project, generated 4 years ago, gets synchronized with latest parent template. https://github.com/MolSSI/cookiecutter-cms/issues/81 --- .github/FUNDING.yml | 4 + .github/PULL_REQUEST_TEMPLATE.md | 9 + .github/workflows/moban-update.yml | 29 +++ .github/workflows/pythonpublish.yml | 26 +++ .gitignore | 1 + .moban.d/LICENSE | 31 --- .../{README.rst => custom_README.rst.jj2} | 0 .moban.d/{setup.py => custom_setup.py.jj2} | 0 .moban.d/requirements.txt | 3 - .moban.yml | 14 +- CHANGELOG.rst | 3 +- CONTRIBUTORS.rst | 6 + LICENSE | 4 +- MANIFEST.in | 2 + Makefile | 14 +- README.rst | 108 +++++++++- format.sh | 3 + libxlsxwpy.yml | 5 + lint.sh | 2 + requirements.txt | 1 + setup.py | 187 +++++++++++++++--- test.bat | 5 +- test.sh | 5 +- tests/requirements.txt | 7 + 24 files changed, 381 insertions(+), 88 deletions(-) create mode 100644 .github/FUNDING.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/workflows/moban-update.yml create mode 100644 .github/workflows/pythonpublish.yml delete mode 100644 .moban.d/LICENSE rename .moban.d/{README.rst => custom_README.rst.jj2} (100%) rename .moban.d/{setup.py => custom_setup.py.jj2} (100%) delete mode 100644 .moban.d/requirements.txt create mode 100644 CONTRIBUTORS.rst create mode 100644 format.sh create mode 100644 lint.sh create mode 100644 requirements.txt diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..0faea60 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,4 @@ +# These are supported funding model platforms + +github: chfw +patreon: chfw diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..6017f21 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +With your PR, here is a check list: + +- [ ] Has test cases written? +- [ ] Has all code lines tested? +- [ ] Has `make format` been run? +- [ ] Please update CHANGELOG.yml(not CHANGELOG.rst) +- [ ] Passes all Travis CI builds +- [ ] Has fair amount of documentation if your change is complex +- [ ] Agree on NEW BSD License for your contribution diff --git a/.github/workflows/moban-update.yml b/.github/workflows/moban-update.yml new file mode 100644 index 0000000..706fd82 --- /dev/null +++ b/.github/workflows/moban-update.yml @@ -0,0 +1,29 @@ +on: [push] + +jobs: + run_moban: + runs-on: ubuntu-latest + name: synchronize templates via moban + steps: + - uses: actions/checkout@v2 + with: + ref: ${{ github.head_ref }} + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: '3.7' + - name: check changes + run: | + pip install moban gitfs2 pypifs moban-jinja2-github moban-ansible + moban + git status + git diff --exit-code + - name: Auto-commit + if: failure() + uses: docker://cdssnc/auto-commit-github-action + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: >- + This is an auto-commit, updating project meta data, + such as changelog.rst, contributors.rst diff --git a/.github/workflows/pythonpublish.yml b/.github/workflows/pythonpublish.yml new file mode 100644 index 0000000..9e7ec42 --- /dev/null +++ b/.github/workflows/pythonpublish.yml @@ -0,0 +1,26 @@ +name: Upload Python Package + +on: + release: + types: [created] + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v1 + - name: Set up Python + uses: actions/setup-python@v1 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install setuptools wheel twine + - name: Build and publish + env: + TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} + TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} + run: | + python setup.py sdist bdist_wheel + twine upload dist/* diff --git a/.gitignore b/.gitignore index c2ece11..5fb5306 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.moban.hashes *.pyc *~ .coverage diff --git a/.moban.d/LICENSE b/.moban.d/LICENSE deleted file mode 100644 index 67b66f1..0000000 --- a/.moban.d/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) {{copyright_year}} by {{company}} and its contributors -All rights reserved. - -Redistribution and use in source and binary forms of the software as well -as documentation, with or without modification, are permitted provided -that the following conditions are met: - -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following -disclaimer in the documentation and/or other materials provided -with the distribution. - -* The names of the contributors may not be used to endorse or -promote products derived from this software without specific -prior written permission. - -THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND -CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT -NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. \ No newline at end of file diff --git a/.moban.d/README.rst b/.moban.d/custom_README.rst.jj2 similarity index 100% rename from .moban.d/README.rst rename to .moban.d/custom_README.rst.jj2 diff --git a/.moban.d/setup.py b/.moban.d/custom_setup.py.jj2 similarity index 100% rename from .moban.d/setup.py rename to .moban.d/custom_setup.py.jj2 diff --git a/.moban.d/requirements.txt b/.moban.d/requirements.txt deleted file mode 100644 index 8337402..0000000 --- a/.moban.d/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -{% for dependency in dependencies: %} -{{dependency}} -{% endfor %} diff --git a/.moban.yml b/.moban.yml index 2b996f4..10fed5a 100644 --- a/.moban.yml +++ b/.moban.yml @@ -1,14 +1,6 @@ +overrides: "git://github.com/pyexcel/pyexcel-mobans!/mobanfile.yaml" configuration: - configuration_dir: "commons/config" - template_dir: - - "commons/templates" - - ".moban.d" configuration: libxlsxwpy.yml targets: - - README.rst: README.rst - - setup.py: setup.py - - LICENSE: LICENSE.jj2 - - MANIFEST.in: MANIFEST.in.jj2 - - test.sh: test.sh.jj2 - - test.bat: test.sh.jj2 - - "tests/requirements.txt": "tests/requirements.txt" + - README.rst: custom_README.rst.jj2 + - setup.py: custom_setup.py.jj2 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index daa3fcc..88d8b57 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,3 +1,2 @@ Change log -====================== - +================================================================================ diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst new file mode 100644 index 0000000..423f980 --- /dev/null +++ b/CONTRIBUTORS.rst @@ -0,0 +1,6 @@ + + +No contributors yet +======================= + +* Your github link will be listed here after your PR is merged diff --git a/LICENSE b/LICENSE index edd438e..fd082c7 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2015-2016 by Onni Software Ltd. and its contributors +Copyright (c) 2015-2020 by Onni Software Ltd. and its contributors All rights reserved. Redistribution and use in source and binary forms of the software as well @@ -27,4 +27,4 @@ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -DAMAGE. \ No newline at end of file +DAMAGE. diff --git a/MANIFEST.in b/MANIFEST.in index 5f13ef0..950deea 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,4 @@ include README.rst +include LICENSE include CHANGELOG.rst +recursive-include tests * diff --git a/Makefile b/Makefile index 4fbbe8b..3e0ee51 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,16 @@ all: test -test: +test: lint bash test.sh + +install_test: + pip install -r tests/requirements.txt + +lint: + bash lint.sh + +format: + bash format.sh + +git-diff-check: + git diff --exit-code diff --git a/README.rst b/README.rst index 949aa6b..887f390 100644 --- a/README.rst +++ b/README.rst @@ -1,21 +1,64 @@ ================================================================================ -libxlsxwpy - Let you focus on data, instead of xlsx format +libxlsxwpy - Let you focus on data, instead of file formats ================================================================================ -.. image:: https://api.travis-ci.org/pyexcel/libxlsxwpy.svg?branch=master +.. image:: https://raw.githubusercontent.com/pyexcel/pyexcel.github.io/master/images/patreon.png + :target: https://www.patreon.com/chfw + +.. image:: https://cdn.rawgit.com/sindresorhus/awesome/d7305f38d29fed78fa85652e3a63e154dd8e8829/media/badge.svg + :target: https://awesome-python.com/#specific-formats-processing + +.. image:: https://travis-ci.org/pyexcel/libxlsxwpy.svg?branch=master :target: http://travis-ci.org/pyexcel/libxlsxwpy -.. image:: https://codecov.io/github/pyexcel/libxlsxwpy/coverage.png - :target: https://codecov.io/github/pyexcel/libxlsxwpy +.. image:: https://codecov.io/gh/pyexcel/libxlsxwpy/branch/master/graph/badge.svg + :target: https://codecov.io/gh/pyexcel/libxlsxwpy +.. image:: https://badge.fury.io/py/libxlsxwpy.svg + :target: https://pypi.org/project/libxlsxwpy + + +.. image:: https://pepy.tech/badge/libxlsxwpy/month + :target: https://pepy.tech/project/libxlsxwpy/month + + +.. image:: https://img.shields.io/gitter/room/gitterHQ/gitter.svg + :target: https://gitter.im/pyexcel/Lobby + +.. image:: https://img.shields.io/static/v1?label=continuous%20templating&message=%E6%A8%A1%E7%89%88%E6%9B%B4%E6%96%B0&color=blue&style=flat-square + :target: https://moban.readthedocs.io/en/latest/#at-scale-continous-templating-for-open-source-projects + +.. image:: https://img.shields.io/static/v1?label=coding%20style&message=black&color=black&style=flat-square + :target: https://github.com/psf/black + +Support the project +================================================================================ + +If your company has embedded pyexcel and its components into a revenue generating +product, please support me on github, `patreon `_ +or `bounty source `_ to maintain +the project and develop it further. + +If you are an individual, you are welcome to support me too and for however long +you feel like. As my backer, you will receive +`early access to pyexcel related contents `_. + +And your issues will get prioritized if you would like to become my patreon as `pyexcel pro user`. + +With your financial support, I will be able to invest +a little bit more time in coding, documentation and writing interesting posts. -**libxlsxwpy** is a plain python wrapper for libxlsxwriter, a c library. And it only support writing strings for now. Known constraints ================== Fonts, colors and charts are not supported. +Introduction +================================================================================ +**libxlsxwpy** is a plain python wrapper for libxlsxwriter, a c library. And it only support writing strings for now. + + Installation ================================================================================ @@ -57,6 +100,61 @@ Here is the python code for `the equivalent C code >> os.unlink("myexcel.xlsx") +Development guide +================================================================================ + +Development steps for code changes + +#. git clone https://github.com/pyexcel/libxlsxwpy.git +#. cd libxlsxwpy + +Upgrade your setup tools and pip. They are needed for development and testing only: + +#. pip install --upgrade setuptools pip + +Then install relevant development requirements: + +#. pip install -r rnd_requirements.txt # if such a file exists +#. pip install -r requirements.txt +#. pip install -r tests/requirements.txt + +Once you have finished your changes, please provide test case(s), relevant documentation +and update CHANGELOG.rst. + +.. note:: + + As to rnd_requirements.txt, usually, it is created when a dependent + library is not released. Once the dependecy is installed + (will be released), the future + version of the dependency in the requirements.txt will be valid. + + +How to test your contribution +------------------------------ + +Although `nose` and `doctest` are both used in code testing, it is adviable that unit tests are put in tests. `doctest` is incorporated only to make sure the code examples in documentation remain valid across different development releases. + +On Linux/Unix systems, please launch your tests like this:: + + $ make + +On Windows systems, please issue this command:: + + > test.bat + + +Before you commit +------------------------------ + +Please run:: + + $ make format + +so as to beautify your code otherwise travis-ci may fail your unit test. + + + + License ================================================================================ diff --git a/format.sh b/format.sh new file mode 100644 index 0000000..1372f52 --- /dev/null +++ b/format.sh @@ -0,0 +1,3 @@ +isort $(find libxlsxwpy -name "*.py"|xargs echo) $(find tests -name "*.py"|xargs echo) +black -l 79 libxlsxwpy +black -l 79 tests diff --git a/libxlsxwpy.yml b/libxlsxwpy.yml index b202e3b..ef9bfc8 100644 --- a/libxlsxwpy.yml +++ b/libxlsxwpy.yml @@ -11,4 +11,9 @@ sources: - pymodule.c - book.c - sheet.c +test_dependencies: + - pyexcel + - pyexcel-xls description: A plain python wrapper for libxlsxwriter, a C library. +python_requires: ">=3.6" +min_python_version: "3.6" diff --git a/lint.sh b/lint.sh new file mode 100644 index 0000000..891aa63 --- /dev/null +++ b/lint.sh @@ -0,0 +1,2 @@ +pip install flake8 +flake8 --exclude=.moban.d,docs,setup.py --builtins=unicode,xrange,long . && python setup.py checkdocs diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..450cd81 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +xlsxwriter diff --git a/setup.py b/setup.py index 7ca6f81..c5d286a 100644 --- a/setup.py +++ b/setup.py @@ -1,28 +1,61 @@ +#!/usr/bin/env python3 + +""" +Template by pypi-mobans +""" + +import os +import sys +import codecs +import locale +import platform +from shutil import rmtree + from distutils.core import setup, Extension -NAME = 'libxlsxwpy' -AUTHOR = 'C.W.' -VERSION = '0.0.1' -EMAIL = 'wangc_2011 (at) hotmail.com' -LICENSE = 'New BSD' + +# Work around mbcs bug in distutils. +# http://bugs.python.org/issue10945 +# This work around is only if a project supports Python < 3.4 + +# Work around for locale not being set +try: + lc = locale.getlocale() + pf = platform.system() + if pf != "Windows" and lc == (None, None): + locale.setlocale(locale.LC_ALL, "C.UTF-8") +except (ValueError, UnicodeError, locale.Error): + locale.setlocale(locale.LC_ALL, "en_US.UTF-8") + +NAME = "libxlsxwpy" +AUTHOR = "chfw" +VERSION = "" +EMAIL = "info@pyexcel.org" +LICENSE = "New BSD" DESCRIPTION = ( - 'A plain python wrapper for libxlsxwriter, a C library.' + - '' + "A plain python wrapper for libxlsxwriter, a C library." ) +URL = "https://github.com/pyexcel/libxlsxwpy" +DOWNLOAD_URL = "%s/archive/0.0.1.tar.gz" % URL +FILES = ["README.rst", "CHANGELOG.rst"] KEYWORDS = [ - 'excel', - 'python', - 'pyexcel', + "python", 'xlsx' ] CLASSIFIERS = [ - 'Topic :: Office/Business', - 'Topic :: Utilities', - 'Topic :: Software Development :: Libraries', - 'Programming Language :: Python', - 'License :: OSI Approved :: BSD License', - 'Intended Audience :: Developers', + "Topic :: Software Development :: Libraries", + "Programming Language :: Python", + "Intended Audience :: Developers", + + "Programming Language :: Python :: 3 :: Only", + + + + "Programming Language :: Python :: 3.6", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + 'Development Status :: 3 - Alpha', 'Programming Language :: Python :: 2.6', 'Programming Language :: Python :: 2.7', @@ -31,46 +64,146 @@ 'Programming Language :: Python :: Implementation :: PyPy' ] +PYTHON_REQUIRES = ">=3.6" + INSTALL_REQUIRES = [ - 'xlsxwriter', + "xlsxwriter", ] - +SETUP_COMMANDS = {} PYMODULE = Extension( 'libxlsxwpy', sources=[ - 'pymodule.c', - 'book.c', - 'sheet.c', + "pymodule.c", + "book.c", + "sheet.c", ], libraries=INSTALL_REQUIRES ) +# You do not need to read beyond this line +PUBLISH_COMMAND = "{0} setup.py sdist bdist_wheel upload -r pypi".format(sys.executable) +GS_COMMAND = ("gs libxlsxwpy v0.0.1 " + + "Find 0.0.1 in changelog for more details") +NO_GS_MESSAGE = ("Automatic github release is disabled. " + + "Please install gease to enable it.") +UPLOAD_FAILED_MSG = ( + 'Upload failed. please run "%s" yourself.' % PUBLISH_COMMAND) +HERE = os.path.abspath(os.path.dirname(__file__)) + + +class PublishCommand(Command): + """Support setup.py upload.""" + + description = "Build and publish the package on github and pypi" + user_options = [] + + @staticmethod + def status(s): + """Prints things in bold.""" + print("\033[1m{0}\033[0m".format(s)) + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + try: + self.status("Removing previous builds...") + rmtree(os.path.join(HERE, "dist")) + rmtree(os.path.join(HERE, "build")) + rmtree(os.path.join(HERE, "libxlsxwpy.egg-info")) + except OSError: + pass + + self.status("Building Source and Wheel (universal) distribution...") + run_status = True + if has_gease(): + run_status = os.system(GS_COMMAND) == 0 + else: + self.status(NO_GS_MESSAGE) + if run_status: + if os.system(PUBLISH_COMMAND) != 0: + self.status(UPLOAD_FAILED_MSG) + + sys.exit() + + +SETUP_COMMANDS.update({ + "publish": PublishCommand +}) + + +def has_gease(): + """ + test if github release command is installed + + visit http://github.com/moremoban/gease for more info + """ + try: + import gease # noqa + return True + except ImportError: + return False def read_files(*files): """Read files into setup""" text = "" for single_file in files: - text = text + read(single_file) + "\n" + content = read(single_file) + text = text + content + "\n" return text def read(afile): """Read a file into setup""" - with open(afile, 'r') as opened_file: - return opened_file.read() + the_relative_file = os.path.join(HERE, afile) + with codecs.open(the_relative_file, "r", "utf-8") as opened_file: + content = filter_out_test_code(opened_file) + content = "".join(list(content)) + return content + + +def filter_out_test_code(file_handle): + found_test_code = False + for line in file_handle.readlines(): + if line.startswith(".. testcode:"): + found_test_code = True + continue + if found_test_code is True: + if line.startswith(" "): + continue + else: + empty_line = line.strip() + if len(empty_line) == 0: + continue + else: + found_test_code = False + yield line + else: + for keyword in ["|version|", "|today|"]: + if keyword in line: + break + else: + yield line -if __name__ == '__main__': +if __name__ == "__main__": setup( + test_suite="tests", name=NAME, author=AUTHOR, version=VERSION, author_email=EMAIL, description=DESCRIPTION, - long_description=read_files('README.rst', 'CHANGELOG.rst'), + url=URL, + download_url=DOWNLOAD_URL, + long_description=read_files(*FILES), license=LICENSE, keywords=KEYWORDS, ext_modules=[PYMODULE], - classifiers=CLASSIFIERS + classifiers=CLASSIFIERS, + cmdclass=SETUP_COMMANDS ) diff --git a/test.bat b/test.bat index 99d6c6c..4c9e1f0 100644 --- a/test.bat +++ b/test.bat @@ -1,4 +1,3 @@ - - +#/bin/bash pip freeze -nosetests --with-cov --cover-package libxlsxwpy --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst && flake8 . --exclude=.moban.d --builtins=unicode,xrange,long +nosetests --with-coverage --cover-package libxlsxwpy --cover-package tests tests --with-doctest --doctest-extension=.rst README.rst docs/source diff --git a/test.sh b/test.sh index 99d6c6c..4c9e1f0 100644 --- a/test.sh +++ b/test.sh @@ -1,4 +1,3 @@ - - +#/bin/bash pip freeze -nosetests --with-cov --cover-package libxlsxwpy --cover-package tests --with-doctest --doctest-extension=.rst tests README.rst && flake8 . --exclude=.moban.d --builtins=unicode,xrange,long +nosetests --with-coverage --cover-package libxlsxwpy --cover-package tests tests --with-doctest --doctest-extension=.rst README.rst docs/source diff --git a/tests/requirements.txt b/tests/requirements.txt index f13a9b5..b53e1a6 100644 --- a/tests/requirements.txt +++ b/tests/requirements.txt @@ -1,6 +1,13 @@ nose +mock;python_version<"3" codecov coverage flake8 +black +isort +collective.checkdocs +pygments +moban +moban_jinja2_github pyexcel pyexcel-xls