├── requirements.txt ├── dev-requirements.txt ├── project_sketch ├── _module │ └── __init__.py └── __init__.py ├── MANIFEST.in ├── .gitignore ├── Makefile ├── LICENSE ├── setup.py └── README.md /requirements.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dev-requirements.txt: -------------------------------------------------------------------------------- 1 | pytest 2 | -------------------------------------------------------------------------------- /project_sketch/_module/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | include README.md 3 | include LICENSE 4 | -------------------------------------------------------------------------------- /project_sketch/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Use semantic versioning: MAJOR.MINOR.PATCH 4 | __version__ = '0.1.0' 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac # 2 | .DS_Store 3 | 4 | # Vim swap files # 5 | *.sw[po] 6 | 7 | # Byte-compiled 8 | *.py[cod] 9 | __pycache__/ 10 | 11 | # Distribution / packaging 12 | /build/ 13 | /dist/ 14 | *.egg-info/ 15 | 16 | # Sphinx documentation 17 | docs/_build/ 18 | 19 | # Others # 20 | .virtualenv 21 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: test build 2 | 3 | clean: 4 | rm -rf build dist *.egg-info 5 | 6 | test: 7 | PYTHONPATH=. pytest -v test/ 8 | 9 | build: 10 | python setup.py build 11 | 12 | build-dist: 13 | python setup.py sdist bdist_wheel 14 | 15 | publish: build-dist 16 | python -m twine upload --skip-existing $(shell ls -t dist/*.whl | head -1) 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Xiao Meng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | from setuptools import setup 6 | 7 | 8 | package_name = 'project_sketch' 9 | 10 | 11 | def get_version(): 12 | import ast 13 | 14 | def parse_version(f): 15 | for line in f: 16 | if line.startswith('__version__'): 17 | return ast.parse(line).body[0].value.s 18 | 19 | for i in [package_name + '/__init__.py', package_name + '.py']: 20 | try: 21 | with open(i, 'r') as f: 22 | return parse_version(f) 23 | except IOError: 24 | pass 25 | 26 | 27 | def get_requires(): 28 | try: 29 | with open('requirements.txt', 'r') as f: 30 | requires = [i.split(' ')[0] for i in map(lambda x: x.strip(), f.readlines()) 31 | if i and i[0] not in ['#', '-']] 32 | return requires 33 | except IOError: 34 | return [] 35 | 36 | 37 | def get_long_description(): 38 | try: 39 | with open('README.md', 'r') as f: 40 | return f.read() 41 | except IOError: 42 | return '' 43 | 44 | 45 | setup( 46 | # license='License :: OSI Approved :: MIT License', 47 | name=package_name, 48 | version=get_version(), 49 | author='', 50 | author_email='', 51 | description='', 52 | url='', 53 | long_description=get_long_description(), 54 | long_description_content_type='text/markdown', 55 | packages=[ 56 | 'project_sketch', 57 | 'project_sketch/_module' 58 | ], 59 | # Or use (make sure find_packages is imported from setuptools): 60 | #packages=find_packages(), 61 | # Or if it's a single file package 62 | #py_modules=[package_name], 63 | install_requires=get_requires(), 64 | # including data files 65 | #include_package_data=True, 66 | #package_data={}, 67 | # entry_points={'console_scripts': ['foo = package.module:main_func']} 68 | ) 69 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # project_sketch 2 | 3 | A nerd's boilerplate for your Python project. 4 | 5 | 6 | ## Usage 7 | 8 | ```bash 9 | $ cp -r project_sketch 10 | $ cd 11 | $ mv project_sketch 12 | ``` 13 | 14 | And change every `project_sketch` word into ``. 15 | 16 | 17 | ## Hierarchy 18 | 19 | ``` 20 | project_sketch 21 | ├── project_sketch 22 | │   ├── _module 23 | │   │   └── __init__.py 24 | │   └── __init__.py 25 | ├── .gitignore 26 | ├── setup.py 27 | ├── Makefile 28 | ├── manage.py 29 | ├── requirements.txt 30 | ├── dev-requirements.txt 31 | └── README.md 32 | ``` 33 | 34 | ## Explanation 35 | 36 | - **project_sketch/** 37 | 38 | The Python package of this project, mostly has the same name with root folder 39 | 40 | - **project_sketch/__init__.py** 41 | 42 | Essential file to claim a package, contains `__version__` variable. 43 | 44 | - **project_sketch/_module/** 45 | 46 | A submodule of the project, there's also a necessary `__init__.py` under it. 47 | 48 | you can `cp _module whatever-you-like` to create a new submodule. 49 | 50 | - **.gitignore** 51 | 52 | Simple, effective gitignore, much less verbose than 53 | [this windbag](https://github.com/github/gitignore/blob/master/Python.gitignore) 54 | 55 | - **setup.py** 56 | 57 | You may hate it, but you can't ignore it. This `setup.py` does just what you want, 58 | and it automatically involves `requirements.txt` and `README.md`. 59 | 60 | If you rock, go and dig [this](https://pinboard.in/u:reorx/t:python/t:packaging). 61 | 62 | - **Makefile** 63 | 64 | We love Makefile, not Rakefile nor Gruntfile nor whatever requires extra program. 65 | This awesome Makefile contains three commands at your service: 66 | 67 | * `make build` 68 | 69 | Build Python package with `setup.py`. 70 | 71 | * `make clean` 72 | 73 | Clean files & folders generated by `build`. 74 | 75 | * `make test` 76 | 77 | Run tests (if you have any) with nose. 78 | 79 | - **manage.py** 80 | 81 | Try `pip install click` & `./manage.py ping` to see how it works. 82 | 83 | If you are writing something that needs to run in a complicated way, 84 | and you realize that this sort of code should not be put in the package, 85 | this is what you need. `manage.py` is an entrance script which you can customize 86 | your own command in it. By default, it uses [click](http://click.pocoo.org/3/) 87 | to define commands & options, you can replace it by other things like 88 | [docopt](http://docopt.org/), or [fabric](http://www.fabfile.org/) 89 | (the file should be named `fabfile.py` then), if you prefer. 90 | 91 | If you are writing a pure import-only package, feel free to remove it. 92 | 93 | - **requirements.txt** 94 | 95 | Includes a `click` by default, this file contains packages your project depends on. 96 | 97 | - **dev-requirements.txt** 98 | 99 | Includes a `nose` by default, this file contains packages you need in developing environment, 100 | which are not necessary in production. 101 | 102 | - **README.md** 103 | 104 | A cute, well formatted `README.md` makes people happy. 105 | (True heros love `README.rst` :). 106 | 107 | 108 | ## Questions and Answers 109 | 110 | Q: Why there's no `MANIFEST.in` file in the directory? 111 | 112 | Q: Why there's no `setup.cfg` file in the directory? 113 | 114 | Q: How to build and publish a distribution? 115 | 116 | Q: Should I use wheel as my distribution format? 117 | 118 | > Could be answered from http://python-packaging-user-guide.readthedocs.org/en/latest/distributing/ 119 | --------------------------------------------------------------------------------