Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v1.2 #143

Merged
merged 30 commits into from
Jan 10, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
cba6030
Add demo GIF
jacebrowning Jan 6, 2017
b6e5825
Merge branch 'master' into develop
jacebrowning Jan 6, 2017
8e3f1a5
Make the GIF loop
jacebrowning Jan 6, 2017
9d08fad
Improve color support detection on Windows
jacebrowning Jan 7, 2017
a81f33d
Update CI tooling
jacebrowning Jan 7, 2017
9d12b94
Switch to default mkdocs theme
jacebrowning Jan 7, 2017
b9556ba
Merge pull request #141 from jacebrowning/plumbing/update-tooling
jacebrowning Jan 7, 2017
e03789b
Call 'mkdir' on Windows
jacebrowning Jan 8, 2017
811dddf
Show Windows-specific 'cd' command
jacebrowning Jan 8, 2017
7e574ab
Use 'del' and 'rmdir' on Windows
jacebrowning Jan 8, 2017
8a30900
Refactor shell checks
jacebrowning Jan 8, 2017
174a47f
Use the current directory for temporary files
jacebrowning Jan 8, 2017
cda80fe
Use the current directory for temporary files
jacebrowning Jan 8, 2017
f222940
Expect symlink creation to fail on Windows
jacebrowning Jan 8, 2017
350f679
Remove Windows support documentation from 1.1
jacebrowning Jan 9, 2017
1887b66
Normalize file paths
jacebrowning Jan 9, 2017
5c28570
Rely on cached dependencies
jacebrowning Jan 9, 2017
cf9d7bc
Return to the root before deleting directories
jacebrowning Jan 9, 2017
34b3dc1
Warn when using the link feature on Windows
jacebrowning Jan 9, 2017
c25563f
Expect link tests to fail on Windows
jacebrowning Jan 9, 2017
4210fdc
Use the same log path format on Windows
jacebrowning Jan 9, 2017
d6cd607
Expect link tests to fail on Windows
jacebrowning Jan 9, 2017
0e77e78
Merge pull request #142 from jacebrowning/feature/handle-windows-paths
jacebrowning Jan 9, 2017
13c242f
Create invalid repositories in an OS-independent way
jacebrowning Jan 9, 2017
08142e3
Only create directory when needed
jacebrowning Jan 9, 2017
6ef34bb
Credit @StudioEtrange for Windows support
jacebrowning Jan 9, 2017
0769308
Use shell functions in tests
jacebrowning Jan 9, 2017
bbeae5f
Ignore invalid git repositories when displaying changes
jacebrowning Jan 9, 2017
efa2f21
Clean up changes after the test
jacebrowning Jan 9, 2017
9fd2c7c
Bump version to 1.2
jacebrowning Jan 10, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
environment:
global:
RANDOM_SEED: 0
matrix:
- PYTHON_MAJOR: 3
PYTHON_MINOR: 5

cache:
- env

Expand All @@ -14,6 +21,6 @@ install:
build: off

test_script:
- make test
- make check
- make test
- make demo
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/demo
/tmp
*/tests/files/gitman_sources

# Temporary Python files
Expand Down
2 changes: 1 addition & 1 deletion .pep8rc → .pycodestyle.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[pep8]
[pycodestyle]

# E401 multiple imports on one line (checked by PyLint)
# E402 module level import not at top of file (checked by PyLint)
Expand Down
2 changes: 1 addition & 1 deletion .pep257 → .pydocstyle
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[pep257]
[pydocstyle]

# D211: No blank lines allowed before class docstring
add_select = D211
Expand Down
2 changes: 1 addition & 1 deletion .pylintrc → .pylint.ini
Original file line number Diff line number Diff line change
@@ -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,missing-docstring
disable=locally-disabled,fixme,too-few-public-methods,too-many-public-methods,invalid-name,global-statement,too-many-ancestors,missing-docstring,no-member

[FORMAT]

Expand Down
17 changes: 10 additions & 7 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
checks:
python:
code_rating: true
duplicate_code: true
python:
code_rating: true
duplicate_code: true
tools:
external_code_coverage: true
pylint:
python_version: 3
config_file: '.pylintrc'
external_code_coverage: true
pylint:
python_version: 3
config_file: '.pylintrc'
filter:
excluded_paths:
- "*/tests/*"
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ after_success:
notifications:
email:
on_success: never
on_failure: change
on_failure: never
File renamed without changes.
5 changes: 4 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Revision History

## 1.2 (2017/01/08)

- Added preliminary Windows support (@StudioEtrange).

## 1.1 (2017/01/06)

- Added coloring to the command-line output.
- Added preliminary Windows support.
- Fixed issue where `<dirty>` could be saved as a locked revision.

## 1.0.2 (2016/07/28)
Expand Down
41 changes: 19 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
PROJECT := GitMan
PACKAGE := gitman
REPOSITORY := jacebrowning/gitman

# Project paths
PACKAGES := $(PACKAGE) tests
CONFIG := $(shell ls *.py)
MODULES := $(shell find $(PACKAGES) -name '*.py') $(CONFIG)
CONFIG := $(wildcard *.py)
MODULES := $(wildcard $(PACKAGE)/*.py)

# Python settings
ifndef TRAVIS
Expand Down Expand Up @@ -62,7 +64,7 @@ HONCHO := $(ACTIVATE) && $(BIN)/honcho
# MAIN TASKS ###################################################################

.PHONY: all
all: doc
all: install

.PHONY: ci
ci: check test demo ## Run all tasks that determine CI status
Expand All @@ -78,8 +80,6 @@ demo: install
$(BIN)/gitman list
$(BIN)/gitman lock
$(BIN)/gitman uninstall
$(BIN)/gitman show
- $(BIN)/gitman edit

# SYSTEM DEPENDENCIES ##########################################################

Expand Down Expand Up @@ -124,29 +124,24 @@ $(PYTHON):

# CHECKS #######################################################################

PEP8 := $(BIN)/pep8
PEP8RADIUS := $(BIN)/pep8radius
PEP257 := $(BIN)/pep257
PYLINT := $(BIN)/pylint
PYCODESTYLE := $(BIN)/pycodestyle
PYDOCSTYLE := $(BIN)/pydocstyle

.PHONY: check
check: pep8 pep257 pylint ## Run linters and static analysis

.PHONY: pep8
pep8: install ## Check for convention issues
$(PEP8) $(PACKAGES) $(CONFIG) --config=.pep8rc

.PHONY: pep257
pep257: install ## Check for docstring issues
$(PEP257) $(PACKAGES) $(CONFIG)
check: pylint pycodestyle pydocstyle ## Run linters and static analysis

.PHONY: pylint
pylint: install ## Check for code issues
$(PYLINT) $(PACKAGES) $(CONFIG) --rcfile=.pylintrc
$(PYLINT) $(PACKAGES) $(CONFIG) --rcfile=.pylint.ini

.PHONY: pycodestyle
pycodestyle: install ## Check for code conventions
$(PYCODESTYLE) $(PACKAGES) $(CONFIG) --config=.pycodestyle.ini

.PHONY: fix
fix: install
$(PEP8RADIUS) --docformatter --in-place
.PHONY: pydocstyle
pydocstyle: install ## Check for docstring conventions
$(PYDOCSTYLE) $(PACKAGES) $(CONFIG)

# TESTS ########################################################################

Expand Down Expand Up @@ -179,12 +174,14 @@ test-unit: install ## Run the unit tests
.PHONY: test-int
test-int: install ## Run the integration tests
@ if test -e $(FAILURES); then TEST_INTEGRATION=true $(PYTEST) $(PYTEST_OPTS_FAILFAST) tests; fi
$(PYTEST) $(PYTEST_OPTS) tests --junitxml=$(REPORTS)/integration.xml
@ rm -rf $(FAILURES)
TEST_INTEGRATION=true $(PYTEST) $(PYTEST_OPTS) tests --junitxml=$(REPORTS)/integration.xml
$(COVERAGE_SPACE) $(REPOSITORY) integration

.PHONY: test-all
test-all: install ## Run all the tests
@ if test -e $(FAILURES); then TEST_INTEGRATION=true $(PYTEST) $(PYTEST_OPTS_FAILFAST) $(PACKAGES); fi
@ rm -rf $(FAILURES)
TEST_INTEGRATION=true $(PYTEST) $(PYTEST_OPTS) $(PACKAGES) --junitxml=$(REPORTS)/overall.xml
$(COVERAGE_SPACE) $(REPOSITORY) overall

Expand Down
Binary file added docs/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion gitman/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys

__project__ = 'GitMan'
__version__ = '1.1'
__version__ = '1.2'

CLI = 'gitman'
PLUGIN = 'deps'
Expand Down
13 changes: 7 additions & 6 deletions gitman/common.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Common exceptions, classes, and functions."""

import os
import sys
import argparse
import logging
Expand Down Expand Up @@ -140,9 +141,10 @@ def show(message="", color=None,
)


def style(msg, name, tty=None):
color_support = sys.stdout.isatty() if tty is None else tty
if not color_support:
def style(msg, name):
is_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty()
supports_ansi = sys.platform != 'win32' or 'ANSICON' in os.environ
if not (is_tty and supports_ansi):
return msg

if name == 'shell':
Expand All @@ -153,7 +155,6 @@ def style(msg, name, tty=None):
return color + msg + RESET

if msg:
assert color is not None
return msg
assert color is not None, "Unknown style name requested"

return ""
return msg
12 changes: 7 additions & 5 deletions gitman/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import logging
from contextlib import suppress

from . import common
from .shell import call
Expand Down Expand Up @@ -50,13 +51,13 @@ def changes(include_untracked=False, display_status=True, _show=False):
status = False

try:
# refresh changes
# Refresh changes
git('update-index', '-q', '--refresh', _show=False)

# check for uncommitted changes
# Check for uncommitted changes
git('diff-index', '--quiet', 'HEAD', _show=_show)

# check for untracked files
# Check for untracked files
output = git('ls-files', '--others', '--exclude-standard', _show=_show)

except ShellError:
Expand All @@ -66,8 +67,9 @@ def changes(include_untracked=False, display_status=True, _show=False):
status = bool(output.splitlines()) and include_untracked

if status and display_status:
for line in git('status', _show=True).splitlines():
common.show(line, color='changes')
with suppress(ShellError):
for line in git('status', _show=True).splitlines():
common.show(line, color='changes')

return status

Expand Down
7 changes: 4 additions & 3 deletions gitman/models/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ def config_path(self):
@property
def log_path(self):
"""Get the full path to the log file."""
return os.path.join(self.location_path, self.LOG)
return os.path.normpath(os.path.join(self.location_path, self.LOG))

@property
def location_path(self):
"""Get the full path to the dependency storage location."""
return os.path.join(self.root, self.location)
return os.path.normpath(os.path.join(self.root, self.location))

def get_path(self, name=None):
"""Get the full path to a dependency or internal file."""
Expand All @@ -54,7 +54,7 @@ def get_path(self, name=None):
elif name == '__log__':
return self.log_path
elif name:
return os.path.join(base, name)
return os.path.normpath(os.path.join(base, name))
else:
return base

Expand Down Expand Up @@ -145,6 +145,7 @@ def lock_dependencies(self, *names, obey_existing=True):

def uninstall_dependencies(self):
"""Delete the dependency storage location."""
shell.cd(self.root)
shell.rm(self.location_path)
common.show()

Expand Down
38 changes: 24 additions & 14 deletions gitman/models/source.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import logging
import warnings

import yorm
from yorm.types import String, AttributeDictionary
Expand Down Expand Up @@ -83,20 +84,29 @@ def update_files(self, force=False, fetch=False, clean=True):

def create_link(self, root, force=False):
"""Create a link from the target name to the current directory."""
if self.link:
log.info("Creating a symbolic link...")
target = os.path.join(root, self.link)
source = os.path.relpath(os.getcwd(), os.path.dirname(target))
if os.path.islink(target):
os.remove(target)
elif os.path.exists(target):
if force:
shell.rm(target)
else:
common.show()
msg = "Preexisting link location at {}".format(target)
raise UncommittedChanges(msg)
shell.ln(source, target)
if not self.link:
return

log.info("Creating a symbolic link...")

if os.name == 'nt':
warnings.warn("Symbolic links are not supported on Windows")
return

target = os.path.join(root, self.link)
source = os.path.relpath(os.getcwd(), os.path.dirname(target))

if os.path.islink(target):
os.remove(target)
elif os.path.exists(target):
if force:
shell.rm(target)
else:
common.show()
msg = "Preexisting link location at {}".format(target)
raise UncommittedChanges(msg)

shell.ln(source, target)

def identify(self, allow_dirty=True, allow_missing=True):
"""Get the path and current repository URL and hash."""
Expand Down
25 changes: 15 additions & 10 deletions gitman/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os
import subprocess
import logging
import shutil

from . import common
from .exceptions import ShellError
Expand Down Expand Up @@ -54,13 +53,18 @@ def call(name, *args, _show=True, _ignore=False, _shell=False):


def mkdir(path):
show('mkdir', '-p', path)
if not os.path.exists(path):
os.makedirs(path)
if os.name == 'nt':
call('mkdir', path, _shell=True)
else:
call('mkdir', '-p', path)


def cd(path, _show=True):
show('cd', path, stdout=_show)
if os.name == 'nt':
show('cd', '/D', path, stdout=_show)
else:
show('cd', path, stdout=_show)
os.chdir(path)


Expand All @@ -75,12 +79,13 @@ def ln(source, target):


def rm(path):
show('rm', '-rf', path)
if os.path.exists(path):
if os.path.isdir(path):
shutil.rmtree(path)
else:
os.remove(path)
if os.name == 'nt':
if os.path.isfile(path):
call('del', '/Q', '/F', path, _shell=True)
elif os.path.isdir(path):
call('rmdir', '/Q', '/S', path, _shell=True)
else:
call('rm', '-rf', path)


def show(name, *args, stdout=True):
Expand Down
7 changes: 0 additions & 7 deletions gitman/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1 @@
"""Unit tests for the package."""


def assert_calls(mock_call, expected):
"""Confirm the expected list of calls matches the mock call."""
__tracebackhide__ = True # pylint: disable=unused-variable
actual = [' '.join(args[0]) for args in mock_call.call_args_list]
assert expected == actual
2 changes: 1 addition & 1 deletion gitman/tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Unit test configuration."""
"""Unit test configuration file."""

import os
import logging
Expand Down
Loading