diff --git a/.coveragerc b/.coveragerc index 7de943d9..b46d51a5 100644 --- a/.coveragerc +++ b/.coveragerc @@ -2,4 +2,4 @@ branch = true omit = */env/* - */test/* + */tests/* diff --git a/.gitignore b/.gitignore index 42c14afc..a796a27e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -*/test/files/src +*/tests/files/gitman_sources # Temporary Python files *.pyc @@ -19,7 +19,7 @@ Icon* # Generated documentation /docs/gen -/apidocs +/docs/apidocs /site /*.html /*.rst diff --git a/.pep257 b/.pep257 index e2641800..e226c3f8 100644 --- a/.pep257 +++ b/.pep257 @@ -3,8 +3,11 @@ # D211: No blank lines allowed before class docstring add_select = D211 +# D100: Missing docstring in public module +# D101: Missing docstring in public class # D102: Missing docstring in public method # D103: Missing docstring in public function +# D104: Missing docstring in public package # D105: Missing docstring in magic method # D202: No blank lines allowed after function docstring -add_ignore = D102,D103,D105,D202 +add_ignore = D100,D101,D102,D103,D104,D105,D202 diff --git a/.pep8rc b/.pep8rc index fb506d68..616e15b8 100644 --- a/.pep8rc +++ b/.pep8rc @@ -1,3 +1,6 @@ [pep8] -ignore = E501,E712 +# E501: line too long (checked by PyLint) +# E711: comparison to None (used to improve test style) +# E712: comparison to True (used to improve test style) +ignore = E501,E711,E712 diff --git a/.pylintrc b/.pylintrc index c82cb82e..1351a184 100644 --- a/.pylintrc +++ b/.pylintrc @@ -1,6 +1,6 @@ [MESSAGES CONTROL] -disable=locally-disabled,fixme,too-few-public-methods,too-many-public-methods,invalid-name,global-statement,too-many-ancestors,misplaced-comparison-constant,missing-docstring +disable=locally-disabled,fixme,too-few-public-methods,too-many-public-methods,invalid-name,global-statement,too-many-ancestors,missing-docstring [FORMAT] diff --git a/.travis.yml b/.travis.yml index 5edbbb32..d0e6c8f3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,40 +12,22 @@ cache: env: global: - RANDOM_SEED=12345 - - secure: "UnyHAJ/T6eI/6vaXXKsZgs2XqBib06DubRqMVegy1nMNBjFsmyZ3tU+22gW2NWAGzukwC3GXWsxkN+7sTlTcTldFBvN9onzC1oVDfQrcAUjvSOK02OZ4tepVq5umsDUxGpRqhWB7LgEv0zM6DHzj6k+yaPBtcJg6NFhpScQfHyY=" install: - pip install coveralls scrutinizer-ocular before_script: - make env -- make depends-ci +- make depends script: -- make ci +- make check +- make test after_success: - coveralls - ocular -after_script: > - echo $TRAVIS_BRANCH; echo $TRAVIS_PULL_REQUEST; - if [[ $TRAVIS_BRANCH == 'develop' && $TRAVIS_PULL_REQUEST == 'false' ]]; then - # Generate site - make mkdocs ; - # Configure Git with Travis CI information - git config --global user.email "travis@travis-ci.org" ; - git config --global user.name "travis-ci" ; - # Delete the current repository - rm -rf .git ; - # Rebuild the repository from the generated files and push to GitHub pages - cd site ; - git init ; - git add . ; - git commit -m "Deploy Travis CI build $TRAVIS_BUILD_NUMBER to GitHub pages" ; - git push -f https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG} master:gh-pages ; - fi - notifications: email: on_success: never diff --git a/CHANGELOG.md b/CHANGELOG.md index c3f0675e..b95cf0c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Revision History +## 1.0.2 (2016/07/28) + +- Moved documentation to http://gitman.readthedocs.io/. + ## 1.0.1 (2016/05/31) - Replaced calls to `git remote add origin` with `git remote set-url origin`. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6584422a..01994fb0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,32 +8,31 @@ * Windows: http://cygwin.com/install.html * Mac: https://developer.apple.com/xcode * Linux: http://www.gnu.org/software/make (likely already installed) -* virtualenv: https://pypi.python.org/pypi/virtualenv#installation * Pandoc: http://johnmacfarlane.net/pandoc/installing.html * Graphviz: http://www.graphviz.org/Download.php ### Installation -Create a virtualenv: +Create a virtual environment: -```sh +``` $ make env ``` -## Development +## Development Tasks ### Testing Manually run the tests: -```sh +``` $ make test $ make tests # includes integration tests ``` or keep them running on change: -```sh +``` $ make watch ``` @@ -43,7 +42,7 @@ $ make watch Build the documentation: -```sh +``` $ make doc ``` @@ -51,18 +50,26 @@ $ make doc Run linters and static analyzers: -```sh +``` $ make pep8 $ make pep257 $ make pylint $ make check # includes all checks ``` -## Release +## Continuous Integration + +The CI server will report overall build status: + +``` +$ make ci +``` + +## Release Tasks Release to PyPI: -```sh +``` $ make upload-test # dry run upload to a test server $ make upload ``` diff --git a/Makefile b/Makefile index 7547ed71..a912c29c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,9 @@ # Project settings PROJECT := GitMan PACKAGE := gitman -SOURCES := Makefile setup.py $(shell find $(PACKAGE) -name '*.py') +REPOSITORY := jacebrowning/gitman +DIRECTORIES := $(PACKAGE) tests +FILES := setup.py $(shell find $(DIRECTORIES) -name '*.py') # Python settings ifndef TRAVIS @@ -12,16 +14,16 @@ endif # System paths PLATFORM := $(shell python -c 'import sys; print(sys.platform)') ifneq ($(findstring win32, $(PLATFORM)), ) - WINDOWS := 1 + WINDOWS := true SYS_PYTHON_DIR := C:\\Python$(PYTHON_MAJOR)$(PYTHON_MINOR) SYS_PYTHON := $(SYS_PYTHON_DIR)\\python.exe # https://bugs.launchpad.net/virtualenv/+bug/449537 export TCL_LIBRARY=$(SYS_PYTHON_DIR)\\tcl\\tcl8.5 else ifneq ($(findstring darwin, $(PLATFORM)), ) - MAC := 1 + MAC := true else - LINUX := 1 + LINUX := true endif SYS_PYTHON := python$(PYTHON_MAJOR) ifdef PYTHON_MINOR @@ -65,152 +67,83 @@ PYTEST := $(BIN_)py.test COVERAGE := $(BIN_)coverage COVERAGE_SPACE := $(BIN_)coverage.space SNIFFER := $(BIN_)sniffer -HONCHO := $(ACTIVATE) && honcho +HONCHO := PYTHONPATH=$(PWD) $(ACTIVATE) && $(BIN_)honcho -# Flags for PHONY targets -INSTALLED_FLAG := $(ENV)/.installed -DEPENDS_CI_FLAG := $(ENV)/.depends-ci -DEPENDS_DOC_FLAG := $(ENV)/.depends-doc -DEPENDS_DEV_FLAG := $(ENV)/.depends-dev -DOCS_FLAG := $(ENV)/.docs -ALL_FLAG := $(ENV)/.all - -# Main Targets ################################################################# +# MAIN TASKS ################################################################### .PHONY: all -all: depends doc $(ALL_FLAG) -$(ALL_FLAG): $(SOURCES) - $(MAKE) check - touch $(ALL_FLAG) # flag to indicate all setup steps were successful +all: doc .PHONY: ci -ifdef TRAVIS -ci: check test tests -else -ci: doc check test tests -endif +ci: check test ## Run all targets that determine CI status .PHONY: watch -watch: depends .clean-test - @ rm -rf $(FAILED_FLAG) +watch: depends .clean-test ## Continuously run all CI targets when files chanage $(SNIFFER) -# Development Installation ##################################################### +# SYSTEM DEPENDENCIES ########################################################## -.PHONY: env -env: $(PIP) $(INSTALLED_FLAG) -$(INSTALLED_FLAG): Makefile setup.py requirements.txt - VIRTUAL_ENV=$(ENV) $(PYTHON) setup.py develop - @ touch $(INSTALLED_FLAG) # flag to indicate package is installed +.PHONY: doctor +doctor: ## Confirm system dependencies are available + @ echo "Checking Python version:" + @ python --version | tee /dev/stderr | grep -q "3.5." -$(PIP): - $(SYS_PYTHON) -m venv --clear $(ENV) - $(PIP) install --upgrade pip setuptools +# PROJECT DEPENDENCIES ######################################################### -# Tools Installation ########################################################### +DEPENDS := $(ENV)/.depends +DEPENDS_CI := $(ENV)/.depends-ci +DEPENDS_DEV := $(ENV)/.depends-dev + +env: $(PYTHON) + +$(PYTHON): + $(SYS_PYTHON) -m venv --clear $(ENV) + $(PYTHON) -m pip install --upgrade pip setuptools .PHONY: depends -depends: depends-ci depends-doc depends-dev - -.PHONY: depends-ci -depends-ci: env Makefile $(DEPENDS_CI_FLAG) -$(DEPENDS_CI_FLAG): Makefile - $(PIP) install --upgrade pep8 pep257 pylint coverage coverage.space pytest pytest-describe pytest-expecter pytest-cov pytest-random freezegun - @ touch $(DEPENDS_CI_FLAG) # flag to indicate dependencies are installed - -.PHONY: depends-doc -depends-doc: env Makefile $(DEPENDS_DOC_FLAG) -$(DEPENDS_DOC_FLAG): Makefile - $(PIP) install --upgrade pylint docutils readme pdoc mkdocs pygments - @ touch $(DEPENDS_DOC_FLAG) # flag to indicate dependencies are installed - -.PHONY: depends-dev -depends-dev: env Makefile $(DEPENDS_DEV_FLAG) -$(DEPENDS_DEV_FLAG): Makefile - $(PIP) install --upgrade pip pep8radius wheel sniffer +depends: env $(DEPENDS) $(DEPENDS_CI) $(DEPENDS_DEV) ## Install all project dependnecies + +$(DEPENDS): setup.py requirements.txt + $(PYTHON) setup.py develop + @ touch $@ # flag to indicate dependencies are installed + +$(DEPENDS_CI): requirements/ci.txt + $(PIP) install -r $^ + @ touch $@ # flag to indicate dependencies are installed + +$(DEPENDS_DEV): requirements/dev.txt + $(PIP) install pip -r $^ ifdef WINDOWS - $(PIP) install --upgrade pywin32 + @ echo "Manually install pywin32: https://sourceforge.net/projects/pywin32/files/pywin32" else ifdef MAC - $(PIP) install --upgrade pync MacFSEvents==0.4 + $(PIP) install --upgrade pync MacFSEvents else ifdef LINUX $(PIP) install --upgrade pyinotify endif - @ touch $(DEPENDS_DEV_FLAG) # flag to indicate dependencies are installed - -# Documentation ################################################################ - -URL := "git-dependency-manager.info" - -.PHONY: doc -doc: readme verify-readme uml apidocs mkdocs - -.PHONY: doc-live -doc-live: doc - eval "sleep 3; open http://127.0.0.1:8000" & - $(MKDOCS) serve - -.PHONY: read -read: doc - $(OPEN) site/index.html - $(OPEN) apidocs/$(PACKAGE)/index.html - $(OPEN) README-pypi.html - $(OPEN) README-github.html - -.PHONY: readme -readme: depends-doc README-github.html README-pypi.html -README-github.html: README.md - pandoc -f markdown_github -t html -o README-github.html README.md -README-pypi.html: README.rst - $(RST2HTML) README.rst README-pypi.html -%.rst: %.md - pandoc -f markdown_github -t rst -o $@ $< - -.PHONY: verify-readme -verify-readme: $(DOCS_FLAG) -$(DOCS_FLAG): README.rst CHANGELOG.rst - $(PYTHON) setup.py check --restructuredtext --strict --metadata - @ touch $(DOCS_FLAG) # flag to indicate README has been checked - -.PHONY: uml -uml: depends-doc docs/*.png -docs/*.png: $(SOURCES) - $(PYREVERSE) $(PACKAGE) -p $(PACKAGE) -a 1 -f ALL -o png --ignore test - - mv -f classes_$(PACKAGE).png docs/classes.png - - mv -f packages_$(PACKAGE).png docs/packages.png + @ touch $@ # flag to indicate dependencies are installed -.PHONY: apidocs -apidocs: depends-doc apidocs/$(PACKAGE)/index.html -apidocs/$(PACKAGE)/index.html: $(SOURCES) - $(PDOC) --html --overwrite $(PACKAGE) --html-dir apidocs - -.PHONY: mkdocs -mkdocs: depends-doc site/index.html -site/index.html: mkdocs.yml docs/*.md - $(MKDOCS) build --clean --strict - echo $(URL) > site/CNAME - -# Static Analysis ############################################################## +# CHECKS ####################################################################### .PHONY: check -check: pep8 pep257 pylint +check: pep8 pep257 pylint ## Run all static analysis targets .PHONY: pep8 -pep8: depends-ci - $(PEP8) $(PACKAGE) tests --config=.pep8rc +pep8: depends ## Check for convention issues + $(PEP8) $(DIRECTORIES) --config=.pep8rc .PHONY: pep257 -pep257: depends-ci - $(PEP257) $(PACKAGE) tests +pep257: depends ## Check for docstring issues + $(PEP257) $(DIRECTORIES) .PHONY: pylint -pylint: depends-ci - $(PYLINT) $(PACKAGE) tests --rcfile=.pylintrc +pylint: depends ## Check for code issues + $(PYLINT) $(DIRECTORIES) --rcfile=.pylintrc .PHONY: fix -fix: depends-dev +fix: depends $(PEP8RADIUS) --docformatter --in-place -# Testing ###################################################################### +# TESTS ######################################################################## RANDOM_SEED ?= $(shell date +%s) @@ -223,90 +156,98 @@ PYTEST_OPTS_FAILFAST := $(PYTEST_OPTS) --last-failed --exitfirst FAILURES := .cache/v/cache/lastfailed -.PHONY: test test-unit -test: test-unit -test-unit: depends-ci +.PHONY: test +test: test-all + +.PHONY: test-unit +test-unit: depends ## Run the unit tests @- mv $(FAILURES) $(FAILURES).bak $(PYTEST) $(PYTEST_OPTS) $(PACKAGE) @- mv $(FAILURES).bak $(FAILURES) ifndef TRAVIS - $(COVERAGE_SPACE) jacebrowning/gitman unit +ifndef APPVEYOR + $(COVERAGE_SPACE) $(REPOSITORY) unit +endif endif .PHONY: test-int -test-int: depends-ci +test-int: depends ## Run the integration tests @ if test -e $(FAILURES); then $(PYTEST) $(PYTEST_OPTS_FAILFAST) tests; fi $(PYTEST) $(PYTEST_OPTS) tests ifndef TRAVIS - $(COVERAGE_SPACE) jacebrowning/gitman integration +ifndef APPVEYOR + $(COVERAGE_SPACE) $(REPOSITORY) integration +endif endif -.PHONY: tests test-all -tests: test-all -test-all: depends-ci - @ if test -e $(FAILURES); then $(PYTEST) $(PYTEST_OPTS_FAILFAST) $(PACKAGE) tests; fi - $(PYTEST) $(PYTEST_OPTS) $(PACKAGE) tests +.PHONY: test-all +test-all: depends ## Run all the tests + @ if test -e $(FAILURES); then $(PYTEST) $(PYTEST_OPTS_FAILFAST) $(DIRECTORIES); fi + $(PYTEST) $(PYTEST_OPTS) $(DIRECTORIES) ifndef TRAVIS - $(COVERAGE_SPACE) jacebrowning/gitman overall +ifndef APPVEYOR + $(COVERAGE_SPACE) $(REPOSITORY) overall +endif endif .PHONY: read-coverage read-coverage: $(OPEN) htmlcov/index.html -# Cleanup ###################################################################### - -.PHONY: clean -clean: .clean-dist .clean-test .clean-doc .clean-build - rm -rf $(ALL_FLAG) +# DOCUMENTATION ################################################################ -.PHONY: clean-all -clean-all: clean .clean-env .clean-workspace +PDOC_INDEX := docs/apidocs/$(PACKAGE)/index.html +MKDOCS_INDEX := site/index.html -.PHONY: .clean-build -.clean-build: - find $(PACKAGE) tests -name '*.pyc' -delete - find $(PACKAGE) tests -name '__pycache__' -delete - rm -rf $(INSTALLED_FLAG) *.egg-info - -.PHONY: .clean-doc -.clean-doc: - rm -rf README.rst apidocs *.html docs/*.png site +.PHONY: doc +doc: uml pdoc mkdocs ## Run all documentation targets -.PHONY: .clean-test -.clean-test: - rm -rf .cache .pytest .coverage htmlcov +.PHONY: uml +uml: depends docs/*.png ## Generate UML diagrams for classes and packages +docs/*.png: $(FILES) + $(PYREVERSE) $(PACKAGE) -p $(PACKAGE) -a 1 -f ALL -o png --ignore tests + - mv -f classes_$(PACKAGE).png docs/classes.png + - mv -f packages_$(PACKAGE).png docs/packages.png -.PHONY: .clean-dist -.clean-dist: - rm -rf dist build +.PHONY: pdoc +pdoc: depends $(PDOC_INDEX) ## Generate API documentaiton with pdoc +$(PDOC_INDEX): $(FILES) + $(PDOC) --html --overwrite $(PACKAGE) --html-dir docs/apidocs + @ touch $@ -.PHONY: .clean-env -.clean-env: clean - rm -rf $(ENV) +.PHONY: mkdocs +mkdocs: depends $(MKDOCS_INDEX) ## Build the documentation site with mkdocs +$(MKDOCS_INDEX): mkdocs.yml docs/*.md + ln -sf `realpath README.md --relative-to=docs` docs/index.md + ln -sf `realpath CHANGELOG.md --relative-to=docs/about` docs/about/changelog.md + ln -sf `realpath CONTRIBUTING.md --relative-to=docs/about` docs/about/contributing.md + ln -sf `realpath LICENSE.md --relative-to=docs/about` docs/about/license.md + $(MKDOCS) build --clean --strict -.PHONY: .clean-workspace -.clean-workspace: - rm -rf *.sublime-workspace +.PHONY: mkdocs-live +mkdocs-live: mkdocs ## Launch and continuously rebuild the mkdocs site + eval "sleep 3; open http://127.0.0.1:8000" & + $(MKDOCS) serve -# Release ###################################################################### +# RELEASE ###################################################################### .PHONY: register-test -register-test: doc +register-test: README.rst CHANGELOG.rst ## Register the project on the test PyPI $(PYTHON) setup.py register --strict --repository https://testpypi.python.org/pypi +.PHONY: register +register: README.rst CHANGELOG.rst ## Register the project on PyPI + $(PYTHON) setup.py register --strict + .PHONY: upload-test -upload-test: register-test +upload-test: register-test ## Upload the current version to the test PyPI $(PYTHON) setup.py sdist upload --repository https://testpypi.python.org/pypi $(PYTHON) setup.py bdist_wheel upload --repository https://testpypi.python.org/pypi $(OPEN) https://testpypi.python.org/pypi/$(PROJECT) -.PHONY: register -register: doc - $(PYTHON) setup.py register --strict - .PHONY: upload -upload: .git-no-changes register +upload: .git-no-changes register ## Upload the current version to PyPI + $(PYTHON) setup.py check --restructuredtext --strict --metadata $(PYTHON) setup.py sdist upload $(PYTHON) setup.py bdist_wheel upload $(OPEN) https://pypi.python.org/pypi/$(PROJECT) @@ -322,16 +263,47 @@ upload: .git-no-changes register exit -1; \ fi; -# System Installation ########################################################## +%.rst: %.md + pandoc -f markdown_github -t rst -o $@ $< + +# CLEANUP ###################################################################### + +.PHONY: clean +clean: .clean-dist .clean-test .clean-doc .clean-build + +.PHONY: clean-all +clean-all: clean .clean-env .clean-workspace + +.PHONY: .clean-build +.clean-build: + find $(DIRECTORIES) -name '*.pyc' -delete + find $(DIRECTORIES) -name '__pycache__' -delete + rm -rf *.egg-info + +.PHONY: .clean-doc +.clean-doc: + rm -rf README.rst docs/apidocs *.html docs/*.png site + +.PHONY: .clean-test +.clean-test: + rm -rf .cache .pytest .coverage htmlcov + +.PHONY: .clean-dist +.clean-dist: + rm -rf dist build + +.PHONY: .clean-env +.clean-env: clean + rm -rf $(ENV) + +.PHONY: .clean-workspace +.clean-workspace: + rm -rf *.sublime-workspace -.PHONY: develop -develop: - $(SYS_PYTHON) setup.py develop +# HELP ######################################################################### -.PHONY: install -install: - $(SYS_PYTHON) setup.py install +.PHONY: help +help: all + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' -.PHONY: download -download: - pip install $(PROJECT) +.DEFAULT_GOAL := help diff --git a/README.md b/README.md index 449e1ac3..928d75cb 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,12 @@ [![PyPI Version](http://img.shields.io/pypi/v/GitMan.svg)](https://pypi.python.org/pypi/GitMan) [![PyPI Downloads](http://img.shields.io/pypi/dm/GitMan.svg)](https://pypi.python.org/pypi/GitMan) -# Getting Started +# Overview GitMan is a language-agnostic "dependency manager" using Git. It aims to serve as a submodules replacement and provides advanced options for managing versions of nested Git repositories. +# Setup + ## Requirements * Python 3.5+ @@ -52,7 +54,7 @@ Ignore the dependency storage location: $ echo vendor >> .gitignore ``` -# Basic Usage +# Usage See the available commands: @@ -104,7 +106,3 @@ Remove all installed dependencies: ```sh $ gitman uninstall ``` - -# Advanced Options - -See the full documentation at [git-dependency-manager.info](http://git-dependency-manager.info/interfaces/cli/). diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 2a117950..00000000 --- a/docs/index.md +++ /dev/null @@ -1,69 +0,0 @@ -# Git Dependency Manager - -GitMan is a language-agnostic "dependency manager" using Git. It aims to serve as a submodules replacement and provides advanced options for managing versions of nested Git repositories. - -## Requirements - -* Python 3.5+ -* Git 1.8+ (with [stored credentials](setup/git/#stored-credentials)) -* Unix shell (or Cygwin/MinGW/etc. on Windows) - -## Installation - -GitMan can be installed with pip: - -```sh -$ pip install gitman -``` - -or directly from the source code: - -```sh -$ git clone https://github.com/jacebrowning/gitman.git -$ cd gitman -$ python setup.py install -``` - -## Setup - -Create a configuration file (`gitman.yml` or `.gitman.yml`) in the root of your working tree: - -```yaml -location: vendor -sources: -- name: framework - repo: https://github.com/kstenerud/iOS-Universal-Framework - rev: Mk5-end-of-life -- name: coverage - repo: https://github.com/jonreid/XcodeCoverage - rev: master - link: Tools/XcodeCoverage -``` - -Ignore the dependency storage location: - -```sh -$ echo vendor >> .gitignore -``` - -## Basic Usage - -Get all dependencies: - -```sh -$ gitman install -``` - -which will essentially: - -1. create a working tree at _root_/`location`/`name` -2. fetch from `repo` and checkout the specified `rev` -3. symbolically link each `location`/`name` from _root_/`link` (if specified) -4. repeat for all nested working trees containing a configuration file - -where `rev` can be: - -* all or part of a commit SHA: `123def` -* a tag: `v1.0` -* a branch: `master` -* a `rev-parse` date: `'develop@{2015-06-18 10:30:59}'` diff --git a/docs/index.md b/docs/index.md new file mode 120000 index 00000000..32d46ee8 --- /dev/null +++ b/docs/index.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/gitman/__init__.py b/gitman/__init__.py index 04f15ba1..17bfc8d1 100644 --- a/gitman/__init__.py +++ b/gitman/__init__.py @@ -3,7 +3,7 @@ import sys __project__ = 'GitMan' -__version__ = '1.0.1' +__version__ = '1.0.2' CLI = 'gitman' PLUGIN = 'deps' diff --git a/gitman/shell.py b/gitman/shell.py index d052306f..da890ece 100644 --- a/gitman/shell.py +++ b/gitman/shell.py @@ -48,7 +48,7 @@ def call(name, *args, _show=True, _ignore=False): else: message = ( "An external program call failed." + "\n\n" - "In worikng directory: " + os.getcwd() + "\n\n" + "In working directory: " + os.getcwd() + "\n\n" "The following command produced a non-zero return code:" + "\n\n" + program + "\n" + command.stdout diff --git a/gitman/test/__init__.py b/gitman/tests/__init__.py similarity index 100% rename from gitman/test/__init__.py rename to gitman/tests/__init__.py diff --git a/gitman/test/conftest.py b/gitman/tests/conftest.py similarity index 100% rename from gitman/test/conftest.py rename to gitman/tests/conftest.py diff --git a/gitman/test/files/gdm-custom.yml b/gitman/tests/files/gdm-custom.yml similarity index 100% rename from gitman/test/files/gdm-custom.yml rename to gitman/tests/files/gdm-custom.yml diff --git a/gitman/test/files/gdm-default.yml b/gitman/tests/files/gdm-default.yml similarity index 100% rename from gitman/test/files/gdm-default.yml rename to gitman/tests/files/gdm-default.yml diff --git a/gitman/test/files/gitman.yml b/gitman/tests/files/gitman.yml similarity index 100% rename from gitman/test/files/gitman.yml rename to gitman/tests/files/gitman.yml diff --git a/gitman/test/test_cli.py b/gitman/tests/test_cli.py similarity index 100% rename from gitman/test/test_cli.py rename to gitman/tests/test_cli.py diff --git a/gitman/test/test_commands.py b/gitman/tests/test_commands.py similarity index 100% rename from gitman/test/test_commands.py rename to gitman/tests/test_commands.py index fe66633f..18466da6 100644 --- a/gitman/test/test_commands.py +++ b/gitman/tests/test_commands.py @@ -2,10 +2,10 @@ import os -from .conftest import ROOT, FILES - from gitman.commands import _find_root, install, update, display, delete +from .conftest import ROOT, FILES + PROJECT_ROOT = os.path.dirname(os.path.dirname(ROOT)) PROJECT_PARENT = os.path.dirname(PROJECT_ROOT) diff --git a/gitman/test/test_common.py b/gitman/tests/test_common.py similarity index 100% rename from gitman/test/test_common.py rename to gitman/tests/test_common.py diff --git a/gitman/test/test_git.py b/gitman/tests/test_git.py similarity index 100% rename from gitman/test/test_git.py rename to gitman/tests/test_git.py diff --git a/gitman/test/test_models_config.py b/gitman/tests/test_models_config.py similarity index 98% rename from gitman/test/test_models_config.py rename to gitman/tests/test_models_config.py index e47677b6..2c102bb0 100644 --- a/gitman/test/test_models_config.py +++ b/gitman/tests/test_models_config.py @@ -1,4 +1,4 @@ -# pylint: disable=no-self-use,redefined-outer-name,unused-variable,expression-not-assigned +# pylint: disable=no-self-use,redefined-outer-name,unused-variable,expression-not-assigned,misplaced-comparison-constant import pytest from expecter import expect diff --git a/gitman/test/test_models_source.py b/gitman/tests/test_models_source.py similarity index 96% rename from gitman/test/test_models_source.py rename to gitman/tests/test_models_source.py index 259d8a33..c157da3e 100644 --- a/gitman/test/test_models_source.py +++ b/gitman/tests/test_models_source.py @@ -1,4 +1,4 @@ -# pylint: disable=no-self-use,redefined-outer-name +# pylint: disable=no-self-use,redefined-outer-name,misplaced-comparison-constant from unittest.mock import patch, Mock from copy import copy diff --git a/gitman/test/test_plugin.py b/gitman/tests/test_plugin.py similarity index 100% rename from gitman/test/test_plugin.py rename to gitman/tests/test_plugin.py diff --git a/gitman/test/test_shell.py b/gitman/tests/test_shell.py similarity index 97% rename from gitman/test/test_shell.py rename to gitman/tests/test_shell.py index 7f73487a..dd8499a6 100644 --- a/gitman/test/test_shell.py +++ b/gitman/tests/test_shell.py @@ -1,4 +1,4 @@ -# pylint: disable=no-self-use +# pylint: disable=no-self-use,misplaced-comparison-constant from unittest.mock import patch, Mock diff --git a/gitman/test/test_system.py b/gitman/tests/test_system.py similarity index 100% rename from gitman/test/test_system.py rename to gitman/tests/test_system.py diff --git a/mkdocs.yml b/mkdocs.yml index b5dbb959..e26d8cfb 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -2,24 +2,23 @@ site_name: GitMan site_description: A language-agnostic "dependency manager" using Git. site_author: Jace Browning repo_url: https://github.com/jacebrowning/gitman -google_analytics: ['UA-6468614-11', 'git-dependency-manager.info'] -theme: mkdocs +theme: readthedocs pages: -- Home: 'index.md' +- Home: index.md - Setup: - - Git: 'setup/git.md' + - Git: setup/git.md - Interfaces: - Command Line: interfaces/cli.md - Git Plugin: interfaces/plugin.md - Package API: interfaces/api.md -- 'Use Cases': - - 'Replacing Submodules': 'use-cases/submodules.md' - - 'Tracking Branches': 'use-cases/branch-tracking.md' - - 'Linking Feature Branches': 'use-cases/linked-features.md' - - 'Build System Integration': 'use-cases/build-integration.md' +- Use Cases: + - Replacing Submodules: use-cases/submodules.md + - Tracking Branches: use-cases/branch-tracking.md + - Linking Feature Branches: use-cases/linked-features.md + - Build System Integration: use-cases/build-integration.md - About: - - 'Release Notes': 'about/changelog.md' - - Contributing: 'about/contributing.md' - - License: 'about/license.md' + - Release Notes: about/changelog.md + - Contributing: about/contributing.md + - License: about/license.md diff --git a/requirements/ci.txt b/requirements/ci.txt new file mode 100644 index 00000000..fddd1f63 --- /dev/null +++ b/requirements/ci.txt @@ -0,0 +1,17 @@ +# Linters +pep8 +pep257 +pylint + +# Testing +pytest +pytest-describe +pytest-expecter +pytest-cov +pytest-random +expecter +freezegun + +# Coverage +coverage +coverage.space diff --git a/requirements/dev.txt b/requirements/dev.txt new file mode 100644 index 00000000..fdf8f28c --- /dev/null +++ b/requirements/dev.txt @@ -0,0 +1,17 @@ +# Documentation +pylint +docutils +readme +pdoc +mkdocs +pygments + +# Tooling +pep8radius +sniffer + +# Runner +honcho + +# Release +wheel diff --git a/scent.py b/scent.py index 0a7432fd..e1e1b071 100644 --- a/scent.py +++ b/scent.py @@ -1,3 +1,5 @@ +"""Configuration file for sniffer.""" + import os import time import subprocess @@ -11,22 +13,28 @@ notify = Notifier.notify -watch_paths = ['gitman/', 'tests/'] +watch_paths = ["gitman", "tests"] @select_runnable('python') @file_validator -def py_files(filename): - return all((filename.endswith('.py'), - not os.path.basename(filename).startswith('.'))) +def python_files(filename): + """Match Python source files.""" + + return all( + (filename.endswith('.py'), + not os.path.basename(filename).startswith('.')), + ) @runnable def python(*_): + """Run targets for Python.""" for count, (command, title, retry) in enumerate(( - (('make', 'test'), "Unit Tests", True), - (('make', 'tests'), "Integration Tests", False), + (('make', 'test-unit'), "Unit Tests", True), + (('make', 'test-int'), "Integration Tests", False), + (('make', 'test-all'), "Combined Tests", False), (('make', 'check'), "Static Analysis", True), (('make', 'doc'), None, True), ), start=1): @@ -44,6 +52,7 @@ def python(*_): def run(command, title, count, retry): + """Run a command-line program and display the result.""" global _rerun_args if _rerun_args: @@ -73,11 +82,13 @@ def run(command, title, count, retry): def show_notification(message, title): + """Show a user notification.""" if notify and title: notify(message, title=title, group=GROUP) def show_coverage(): + """Launch the coverage report.""" global _show_coverage if _show_coverage: diff --git a/setup.py b/setup.py index 5e482c0a..1ff84cfd 100644 --- a/setup.py +++ b/setup.py @@ -19,7 +19,7 @@ version=__version__, description=DESCRIPTION, - url='http://git-dependency-manager.info', + url='https://jacebrowning/gitman', author='Jace Browning', author_email='jacebrowning@gmail.com', @@ -51,5 +51,5 @@ 'Topic :: System :: Software Distribution', ], - install_requires=open('requirements.txt').readlines(), + install_requires=open("requirements.txt").readlines(), ) diff --git a/tests/conftest.py b/tests/conftest.py index c7290ba5..0e4f9162 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,7 +5,7 @@ import yorm -from gitman.test.conftest import pytest_configure # pylint: disable=unused-import +from gitman.tests.conftest import pytest_configure # pylint: disable=unused-import # TODO: delete if unused (and files)