From a3f387b81fa9c2df1223d2f86b7d4bb5624b5a78 Mon Sep 17 00:00:00 2001 From: Brian Gesiak Date: Fri, 10 Feb 2012 15:54:00 +0900 Subject: [PATCH] Implemented commands. - Each individual pyhoe command is implemented in it's own file. - Changed template to templates. The templates directory will hold several templates in the future. --- builder.py | 12 ++- cmdline.py | 1 + pyhoe.py | 53 +++++++++++++ {template/tests => pyhoe}/__init__.py | 0 pyhoe/commands/__init__.py | 9 +++ pyhoe/commands/startproject.py | 79 +++++++++++++++++++ startproject.py | 42 ---------- {template => templates/package}/.gitignore | 0 {template => templates/package}/CHANGELOG.md | 0 {template => templates/package}/LICENSE | 0 {template => templates/package}/MANIFEST.in | 0 .../package}/PROJECT_NAME/__init__.py | 0 {template => templates/package}/README.md | 0 .../package}/fabfile/__init__.py | 0 .../package}/fabfile/doc.py | 0 .../package}/fabfile/git.py | 0 .../package}/fabfile/project.py | 0 .../package}/fabfile/test.py | 0 {template => templates/package}/setup.py | 0 .../package}/tests/PROJECT_NAME_tests.py | 0 {util => templates/package/tests}/__init__.py | 0 {template => templates/package}/tox.ini | 0 util/delegator.py | 11 --- 23 files changed, 151 insertions(+), 56 deletions(-) create mode 100644 pyhoe.py rename {template/tests => pyhoe}/__init__.py (100%) create mode 100644 pyhoe/commands/__init__.py create mode 100644 pyhoe/commands/startproject.py delete mode 100644 startproject.py rename {template => templates/package}/.gitignore (100%) rename {template => templates/package}/CHANGELOG.md (100%) rename {template => templates/package}/LICENSE (100%) rename {template => templates/package}/MANIFEST.in (100%) rename {template => templates/package}/PROJECT_NAME/__init__.py (100%) rename {template => templates/package}/README.md (100%) rename {template => templates/package}/fabfile/__init__.py (100%) rename {template => templates/package}/fabfile/doc.py (100%) rename {template => templates/package}/fabfile/git.py (100%) rename {template => templates/package}/fabfile/project.py (100%) rename {template => templates/package}/fabfile/test.py (100%) rename {template => templates/package}/setup.py (100%) rename {template => templates/package}/tests/PROJECT_NAME_tests.py (100%) rename {util => templates/package/tests}/__init__.py (100%) rename {template => templates/package}/tox.ini (100%) delete mode 100644 util/delegator.py diff --git a/builder.py b/builder.py index b4d62a7..4ebfcf8 100644 --- a/builder.py +++ b/builder.py @@ -4,7 +4,7 @@ from os.path import join import shutil -TEMPLATE_DIR = "template" +TEMPLATE_DIR = "templates" class ProjectBuilder(object): """ @@ -13,8 +13,14 @@ def __init__(self): """docstring for __init__""" pass - def build(self, project_name, python_exe=None, skip_confirmation=False): + def build( + self, + project_name, + template, + python_exe=None, + skip_confirmation=False + ): print "Building project: %s" % project_name if python_exe: print "Using %s" % python_exe print "Skip confirmation: %s" % str(skip_confirmation) - shutil.copytree(TEMPLATE_DIR, project_name) + shutil.copytree(join(TEMPLATE_DIR, template), project_name) diff --git a/cmdline.py b/cmdline.py index 5cc1582..ea5e6a8 100644 --- a/cmdline.py +++ b/cmdline.py @@ -33,6 +33,7 @@ def execute(self): self.clean_args() build_args = { "project_name": self.args["project_name"], + "template": self.args["template"], "skip_confirmation": self.args["yes_to_all"] } if self.args["python_exe"]: diff --git a/pyhoe.py b/pyhoe.py new file mode 100644 index 0000000..a7d1610 --- /dev/null +++ b/pyhoe.py @@ -0,0 +1,53 @@ +import sys +import types +import argparse +from pyhoe import commands as cmds +from pyhoe.commands import * + +COMMANDS = list(( + cmds.__dict__.get(c) for c in dir(cmds) if isinstance( + cmds.__dict__.get(c), types.ModuleType + ) +)) + +def available_command_names(): + """ + Returns a list of command names in pyhoe.commands. + """ + return [c.__name__.split(".")[-1] for c in COMMANDS] + + +if __name__ == "__main__": + # Instantiate argument parser, add arguments. + parser = argparse.ArgumentParser( + prog="pyhoe", + description = ( + "Provides several convenient functions for developing " + "Python packages and scripts using best practices." + ) + ) + parser.add_argument( + "action", + choices = available_command_names(), + help = "Choose an action for pyhoe to perform." + ) + parser.add_argument( + "options", + nargs = "*", + help = ( + "Add any option flags or positional arguments for " + "the specified action. You can see options by simply " + "entering the action name." + ) + ) + + # Print help if no args provided. + if len(sys.argv) <= 1: + parser.print_help() + sys.exit(0) # TODO - Perhaps exit with error? + + # Pass remaining args to appropriate function. + args = vars(parser.parse_args(sys.argv[1:])) + for c in COMMANDS: + if args["action"] == c.__name__.split(".")[-1]: + c.execute(sys.argv[2:]) diff --git a/template/tests/__init__.py b/pyhoe/__init__.py similarity index 100% rename from template/tests/__init__.py rename to pyhoe/__init__.py diff --git a/pyhoe/commands/__init__.py b/pyhoe/commands/__init__.py new file mode 100644 index 0000000..aa71896 --- /dev/null +++ b/pyhoe/commands/__init__.py @@ -0,0 +1,9 @@ +from os import listdir +from os.path import dirname, splitext +import re + +r = re.compile("^[a-zA-Z0-9]*\.py$") + +__all__ = [ + splitext(m)[0]for m in listdir(dirname(__file__)) if r.match(m) +] diff --git a/pyhoe/commands/startproject.py b/pyhoe/commands/startproject.py new file mode 100644 index 0000000..69c8120 --- /dev/null +++ b/pyhoe/commands/startproject.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import os, sys +import argparse +from cmdline import CommandLineDelegator + +# FIXME - Place this somewhere +TEMPLATE_DIR = "templates" + +def default_temaplate(): + """ + Returns a string representing the default template directory. + """ + default = "package" + if default in os.listdir(TEMPLATE_DIR): + return default + else: + return os.listdir(TEMPLATE_DIR)[0] + + +def parse_cl_args(sysargs): + """ + Uses argparse to handle user input. + Returns a __dict__ representation of + the parsed arguments. + """ + parser = argparse.ArgumentParser( + prog="pyhoe startproject", + description = ( + "Initializes a Python project using established best practices." + ) + ) + parser.add_argument( + "project_name", + help = "The name of the project." + ) + parser.add_argument( + "-c", "--cucumber", + action = "store_true", + help = "Use freshen for behavior-driven development." + ) + parser.add_argument( + "-p", "--python", + dest = "python_exe", + help = ( + "The Python interpreter to use, e.g.: " + "--python=python2.6 will use the Python " + "2.6 interpreter to create any new virtual " + "environments." + ), + ) + parser.add_argument( + "-t", "--template", + choices = os.listdir(TEMPLATE_DIR), + default = default_temaplate(), + help = "The template to use for your project." + ) + parser.add_argument( + "-y", "--yes-to-all", + action = "store_true", + help = ( + "Skip all confirmation and use recommended settings." + ) + ) + return vars(parser.parse_args(sysargs)) + + +def execute(args=None): + """ + Parses sys.args or args parameter and executes + the parsed values using CommandLineDelegator. + """ + a = args or sys.argv + delegator = CommandLineDelegator(parse_cl_args(a)) + delegator.execute() + + +if __name__ == "__main__": + execute() diff --git a/startproject.py b/startproject.py deleted file mode 100644 index 70b9305..0000000 --- a/startproject.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python - -import argparse -from cmdline import CommandLineDelegator - -def parse_cl_args(): - """ - Uses argparse to handle user input. - Returns a __dict__ representation of - the parsed arguments. - """ - parser = argparse.ArgumentParser( - description = ( - "Initializes a Python project using established best practices." - ) - ) - parser.add_argument( - "project_name", - help = "The name of the project." - ) - parser.add_argument( - "-p", "--python", - dest = "python_exe", - help = ( - "The Python interpreter to use, e.g.: " - "--python=python2.6 will use the Python " - "2.6 interpreter to create any new virtual " - "environments." - ), - ) - parser.add_argument( - "-y", "--yes-to-all", - action = "store_true", - help = ( - "Skip all confirmation and use recommended settings." - ) - ) - return vars(parser.parse_args()) - -if __name__ == "__main__": - delegator = CommandLineDelegator(parse_cl_args()) - delegator.execute() diff --git a/template/.gitignore b/templates/package/.gitignore similarity index 100% rename from template/.gitignore rename to templates/package/.gitignore diff --git a/template/CHANGELOG.md b/templates/package/CHANGELOG.md similarity index 100% rename from template/CHANGELOG.md rename to templates/package/CHANGELOG.md diff --git a/template/LICENSE b/templates/package/LICENSE similarity index 100% rename from template/LICENSE rename to templates/package/LICENSE diff --git a/template/MANIFEST.in b/templates/package/MANIFEST.in similarity index 100% rename from template/MANIFEST.in rename to templates/package/MANIFEST.in diff --git a/template/PROJECT_NAME/__init__.py b/templates/package/PROJECT_NAME/__init__.py similarity index 100% rename from template/PROJECT_NAME/__init__.py rename to templates/package/PROJECT_NAME/__init__.py diff --git a/template/README.md b/templates/package/README.md similarity index 100% rename from template/README.md rename to templates/package/README.md diff --git a/template/fabfile/__init__.py b/templates/package/fabfile/__init__.py similarity index 100% rename from template/fabfile/__init__.py rename to templates/package/fabfile/__init__.py diff --git a/template/fabfile/doc.py b/templates/package/fabfile/doc.py similarity index 100% rename from template/fabfile/doc.py rename to templates/package/fabfile/doc.py diff --git a/template/fabfile/git.py b/templates/package/fabfile/git.py similarity index 100% rename from template/fabfile/git.py rename to templates/package/fabfile/git.py diff --git a/template/fabfile/project.py b/templates/package/fabfile/project.py similarity index 100% rename from template/fabfile/project.py rename to templates/package/fabfile/project.py diff --git a/template/fabfile/test.py b/templates/package/fabfile/test.py similarity index 100% rename from template/fabfile/test.py rename to templates/package/fabfile/test.py diff --git a/template/setup.py b/templates/package/setup.py similarity index 100% rename from template/setup.py rename to templates/package/setup.py diff --git a/template/tests/PROJECT_NAME_tests.py b/templates/package/tests/PROJECT_NAME_tests.py similarity index 100% rename from template/tests/PROJECT_NAME_tests.py rename to templates/package/tests/PROJECT_NAME_tests.py diff --git a/util/__init__.py b/templates/package/tests/__init__.py similarity index 100% rename from util/__init__.py rename to templates/package/tests/__init__.py diff --git a/template/tox.ini b/templates/package/tox.ini similarity index 100% rename from template/tox.ini rename to templates/package/tox.ini diff --git a/util/delegator.py b/util/delegator.py deleted file mode 100644 index 5f4b099..0000000 --- a/util/delegator.py +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env python - -class Delegator(object): - """ - Performs commands based on arguments provided. - """ - def __init__(self, args): - self.args = args - for arg in self.args: - print arg - # func = getattr(self, arg)