├── .gitignore ├── LICENSE ├── README.md ├── pyboiler ├── __init__.py ├── pyboiler.py └── serializers.py ├── setup.py └── test_files ├── complex.json ├── perror.json └── simple.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # C extensions 6 | *.so 7 | 8 | # Distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | *.egg-info/ 23 | .installed.cfg 24 | *.egg 25 | 26 | # PyInstaller 27 | # Usually these files are written by a python script from a template 28 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .coverage 40 | .coverage.* 41 | .cache 42 | nosetests.xml 43 | coverage.xml 44 | *,cover 45 | 46 | # Translations 47 | *.mo 48 | *.pot 49 | 50 | # Django stuff: 51 | *.log 52 | 53 | # Sphinx documentation 54 | docs/_build/ 55 | 56 | # PyBuilder 57 | target/ 58 | 59 | # pyenv 60 | .python-version 61 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2014 Bassem Dghaidi 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PyBoiler 2 | PyBoiler is a simple python 2.7 script to create a project template in a given directory. 3 | 4 | ### Version 5 | 6 | alpha-0.3.0 7 | 8 | ### Installation 9 | 10 | pip install pyboiler 11 | 12 | ### Usage 13 | PyBoiler is extremely simple to use. 14 | 15 | ##### Create a JSON file to match the folder structure you desire: 16 | 17 | $: nano structure.json 18 | 19 | # Paste the below into your file and modify as you desire 20 | [{'folder': 'source'}, 21 | {'file': 'source/file1.txt'}, # Nested file 22 | {'folder': 'sublime'}, 23 | {'file': 'sublime/file2.txt'}, 24 | {'folder': 'docs'}, 25 | {'file': 'docs/file3.txt'}, 26 | {'file': 'docs/file4.txt'}, 27 | {'file': 'README.md'}] 28 | 29 | ##### How to execute 30 | 31 | usage: pyboiler.py [-h] -o PROJECT_PATH 32 | 33 | required arguments: 34 | -o PROJECT_PATH, --project-directory PROJECT_PATH 35 | Project's absolute path where the structure will be created 36 | 37 | optional arguments: 38 | -h, --help 39 | Show this help message and exit 40 | 41 | -s FOLDER_STRUCTURE, --folder-structure FOLDER_STRUCTURE 42 | JSON file containing the template folder/file 43 | structure to be created 44 | 45 | Note: If the argument `-i` is not specified the script will use the default template (hardcoded) 46 | 47 | ### Change Log 48 | ### alpha-0.3.0 49 | * Input file argument changed to `-s` instead of `-i` 50 | * Temporarily removed jparser.py in order to make room for further serializers in future releases (XML, yaml etc...) 51 | * Code refactoring and cleanup 52 | 53 | #### alpha-0.2.0 54 | * Folder and File structure template can be imported from a JSON file 55 | * Added jparser.py to parse and validate the JSON file 56 | 57 | ### Tests 58 | This script has been tests on Mac OS X 10.9.4 only. There is no guarantee it will perform as expected on other Operating Systems. 59 | 60 | ### LICENSE 61 | 62 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 63 | 64 | Version 2, December 2004 65 | 66 | Copyright (C) 2014 Bassem Dghaidi 67 | 68 | Everyone is permitted to copy and distribute verbatim or modified 69 | copies of this license document, and changing it is allowed as long 70 | as the name is changed. 71 | 72 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 73 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 74 | 75 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /pyboiler/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | -------------------------------------------------------------------------------- /pyboiler/pyboiler.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # @version: alpha-0.3.0 | python 2.7.x 3 | # - 4 | # @desc: PyBoiler is a simple python script 5 | # that creates the basic folder/file structure 6 | # for simple python projects. 7 | # - 8 | 9 | import argparse 10 | from distutils.util import strtobool 11 | import codecs 12 | import json 13 | import os 14 | 15 | 16 | DEFAULT_FOLDER_STRUCTURE = [ 17 | {'folder': 'source'}, 18 | {'folder': 'sublime'}, 19 | {'folder': 'docs'}, 20 | {'file': 'README.md'} 21 | ] 22 | 23 | 24 | def make_file(path): 25 | """Create an empty file in a given directory""" 26 | open(path, 'a').close() 27 | 28 | 29 | def make_folder(path): 30 | """Create an empty directory""" 31 | if not os.path.exists(path): 32 | os.makedirs(path) 33 | 34 | 35 | def build_structure(target, source, override): 36 | """Builds the folder structure in a given directory""" 37 | if source: 38 | try: 39 | if os.path.isfile(source): 40 | """Handle UTF-8 Files""" 41 | with codecs.open(source, 'rU', 'utf-8') as file_data: 42 | structure = json.load(file_data) 43 | except: 44 | exit('> Fatal error - cannot parse the provided JSON files: %s' % source) 45 | else: 46 | """Use the default structure if the above fails""" 47 | structure = DEFAULT_FOLDER_STRUCTURE 48 | 49 | print('> {} folder structure: {}\n'.format( 50 | 'Overriding' if override else 'Creating', 51 | target)) 52 | 53 | for entry in structure: 54 | for _type, name in entry.iteritems(): 55 | try: 56 | joined = os.path.join(target, name) 57 | if _type == 'folder': 58 | make_folder(joined) 59 | elif _type == 'file': 60 | make_file(joined) 61 | print('Created: %s' % joined) 62 | except OSError: 63 | exit('> Fatal error - exiting...') 64 | 65 | 66 | def user_yes_no_query(question): 67 | """Prompts the user for a choice""" 68 | 69 | print('%s [y/n]:' % question) 70 | 71 | while True: 72 | try: 73 | return strtobool(raw_input().lower()) 74 | except ValueError: 75 | print("Please respond with 'y' or 'n'.") 76 | 77 | 78 | def build_parser(): 79 | """Builds the argument parser""" 80 | parser = argparse.ArgumentParser() 81 | 82 | parser.add_argument( 83 | '-o', '--output-directory', 84 | dest='target', 85 | help='Target output path where the structure will be created', 86 | type=str, 87 | required=True) 88 | 89 | parser.add_argument( 90 | '-s', '--source-file', 91 | dest='source', 92 | help='Source JSON file containing structure to be created', 93 | type=str, 94 | required=False) 95 | 96 | return parser 97 | 98 | 99 | def main(): 100 | args = build_parser().parse_args() 101 | 102 | exists = os.path.exists(args.target) 103 | should_override = lambda: user_yes_no_query( 104 | '> Folder already exists, do you wish to override it?') 105 | 106 | if exists: 107 | if should_override(): 108 | build_structure(args.target, args.source, override=True) 109 | else: 110 | build_structure(args.target, args.source, override=False) 111 | 112 | 113 | if __name__ == "__main__": 114 | main() 115 | -------------------------------------------------------------------------------- /pyboiler/serializers.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # TBD -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import sys, os 3 | 4 | VERSION = '0.3.0' 5 | DESCRIPTION = """\ 6 | Creates a configurable python project template in a given directory.""" 7 | 8 | setup(name='pyboiler', 9 | version=VERSION, 10 | description=DESCRIPTION, 11 | long_description=DESCRIPTION, 12 | classifiers=[ 13 | 'Intended Audience :: Developers', 14 | 'Development Status :: 3 - Alpha', 15 | 'Programming Language :: Python :: 2.7', 16 | 'Topic :: Software Development :: Build Tools' 17 | ], 18 | keywords='boilerplate python script configurable', 19 | author='Link-', 20 | author_email='bsm.dgdy@gmail.com', 21 | url='https://pypi.python.org/pypi/pyboiler', 22 | license='LICENSE', 23 | packages=['pyboiler'], 24 | include_package_data=True, 25 | zip_safe=True, 26 | entry_points={ 27 | 'console_scripts': [ 28 | 'pyboiler = pyboiler.pyboiler:main', 29 | ] 30 | } 31 | ) 32 | -------------------------------------------------------------------------------- /test_files/complex.json: -------------------------------------------------------------------------------- 1 | [{"folder": "source"}, 2 | {"folder": "sublime"}, 3 | {"folder": "docs"}, 4 | {"file": "README.md"}, 5 | {"folder": "hello-baby"}] -------------------------------------------------------------------------------- /test_files/perror.json: -------------------------------------------------------------------------------- 1 | [{"folder": "source"}, 2 | {"folder": "sublime"}, 3 | {"folder": "docs"}, 4 | {"file": "README.md"} -------------------------------------------------------------------------------- /test_files/simple.json: -------------------------------------------------------------------------------- 1 | [{"folder": "source"}, 2 | {"folder": "sublime"}, 3 | {"folder": "docs"}, 4 | {"file": "README.md"}] --------------------------------------------------------------------------------