Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 0 additions & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ environment:
global:
RANDOM_SEED: 0
matrix:
- PYTHON_MAJOR: 3
PYTHON_MINOR: 6
- PYTHON_MAJOR: 3
PYTHON_MINOR: 7
- PYTHON_MAJOR: 3
Expand Down
2 changes: 2 additions & 0 deletions .mypy.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ no_implicit_optional = true
check_untyped_defs = true

cache_dir = .cache/mypy/

plugins = datafiles.plugins:mypy
6 changes: 5 additions & 1 deletion .pylint.ini
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ disable=
redefined-builtin,
too-many-public-methods,
bad-continuation,
subprocess-run-check,
no-member,
not-an-iterable,
unsupported-assignment-operation,
unsubscriptable-object,
too-many-instance-attributes,

# Enable the message, report, category or checker with the given id(s). You can
# either give multiple identifier separated by comma (,) or put this option
Expand Down
1 change: 0 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ dist: xenial

language: python
python:
- 3.6
- 3.7
- 3.8

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# 2.0 (alpha)

- **BREAKING**: Dropped support for Python 3.6.
- Switched to `datafiles` for YAML serialization.

# 1.8 (2020-04-04)

- Added support Python 3.8.
Expand Down
4 changes: 2 additions & 2 deletions gitman/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ def init():
else:
config = Config()
source = Source(
'git',
type='git',
name="sample_dependency",
repo="https://github.com/githubtraining/hellogitworld",
)
config.sources.append(source)
source = source.lock(rev="ebbbf773431ba07510251bb03f9525c7bab2b13a")
config.sources_locked.append(source)
config.save()
config.datafile.save()

msg = "Created sample config file: {}".format(config.path)
common.show(msg, color='success')
Expand Down
3 changes: 2 additions & 1 deletion gitman/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ def configure_logging(count=0):
verbose_format = settings.VERBOSE2_LOGGING_FORMAT

# Set a custom formatter
log.reset() # TODO: this shouldn't be necessary
log.init(level=level)
log.silence('yorm', allow_warning=True)
log.silence('datafiles', allow_warning=True)
logging.captureWarnings(True)
formatter = WarningFormatter(
default_format, verbose_format, datefmt=settings.LOGGING_DATEFMT
Expand Down
2 changes: 1 addition & 1 deletion gitman/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def clone(type, repo, path, *, cache=settings.CACHE, sparse_paths=None, rev=None
if not settings.CACHE_DISABLE and not os.path.isdir(reference):
git('clone', '--mirror', repo, reference)

if sparse_paths:
if sparse_paths and sparse_paths[0]:
os.mkdir(normpath)
git('-C', normpath, 'init')
git('-C', normpath, 'config', 'core.sparseCheckout', 'true')
Expand Down
39 changes: 19 additions & 20 deletions gitman/models/config.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,29 @@
import os
from typing import List
from typing import List, Optional

import log
import yorm
from yorm.types import SortedList, String
from datafiles import datafile, field

from .. import common, exceptions, shell
from .group import Group
from .source import Source


@yorm.attr(location=String)
@yorm.attr(sources=SortedList.of_type(Source))
@yorm.attr(sources_locked=SortedList.of_type(Source))
@yorm.attr(groups=SortedList.of_type(Group))
@yorm.sync("{self.root}/{self.filename}", auto_save=False)
class Config(yorm.ModelMixin):
@datafile("{self.root}/{self.filename}", defaults=True, manual=True)
class Config:
"""Specifies all dependencies for a project."""

LOG = "gitman.log"
root: Optional[str] = None
filename: str = "gitman.yml"

def __init__(self, root=None, filename="gitman.yml", location="gitman_sources"):
super().__init__()
self.root = root or os.getcwd()
self.filename = filename
self.location = location
self.sources: List[Source] = []
self.sources_locked: List[Source] = []
self.groups: List[Group] = []
location: str = "gitman_sources"
sources: List[Source] = field(default_factory=list)
sources_locked: List[Source] = field(default_factory=list)
groups: List[Group] = field(default_factory=list)

def __post_init__(self):
if self.root is None:
self.root = os.getcwd()

def _on_post_load(self):
for source in self.sources:
Expand All @@ -49,18 +45,20 @@ def _on_post_load(self):
@property
def config_path(self):
"""Get the full path to the config file."""
assert self.root
return os.path.normpath(os.path.join(self.root, self.filename))

path = config_path

@property
def log_path(self):
"""Get the full path to the log file."""
return os.path.normpath(os.path.join(self.location_path, self.LOG))
return os.path.normpath(os.path.join(self.location_path, "gitman.log"))

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

def get_path(self, name=None):
Expand Down Expand Up @@ -204,7 +202,7 @@ def lock_dependencies(self, *names, obey_existing=True, skip_changes=False):
shell.cd(self.location_path, _show=False)

if count:
self.save()
self.datafile.save()

common.dedent()

Expand Down Expand Up @@ -240,6 +238,7 @@ def get_top_level_dependencies(self):

for source in self.sources:

assert source.name
yield os.path.join(self.location_path, source.name)

shell.cd(self.location_path, _show=False)
Expand Down
24 changes: 11 additions & 13 deletions gitman/models/group.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import yorm
from yorm.types import AttributeDictionary, List, String
from dataclasses import dataclass
from typing import List

from .. import exceptions


@yorm.attr(name=String)
@yorm.attr(members=List.of_type(String))
class Group(AttributeDictionary):
@dataclass
class Group:
"""A group with sources."""

def __init__(self, name, members):
name: str
members: List[str]

super().__init__()
self.name = name
self.members = members or []

for key in ['name', 'members']:
if not self[key]:
msg = "'{}' required for {}".format(key, repr(self))
def __post_init__(self):
# TODO: Remove this?
for name in ['name', 'members']:
if not getattr(self, name):
msg = "'{}' required for {}".format(name, repr(self))
raise exceptions.InvalidConfig(msg)

def __repr__(self):
Expand Down
71 changes: 31 additions & 40 deletions gitman/models/source.py
Original file line number Diff line number Diff line change
@@ -1,51 +1,39 @@
import os
from dataclasses import dataclass, field
from typing import List, Optional

import log
import yorm
from yorm.types import AttributeDictionary, List, NullableString, String

from .. import common, exceptions, git, shell


@yorm.attr(name=String)
@yorm.attr(type=String)
@yorm.attr(repo=String)
@yorm.attr(sparse_paths=List.of_type(String))
@yorm.attr(rev=String)
@yorm.attr(link=NullableString)
@yorm.attr(scripts=List.of_type(String))
class Source(AttributeDictionary):
@dataclass
class Source:
"""A dictionary of `git` and `ln` arguments."""

name: Optional[str]
type: str
repo: str
sparse_paths: List[str] = field(default_factory=list)
rev: str = 'master'
link: Optional[str] = None
scripts: List[str] = field(default_factory=list)

DIRTY = '<dirty>'
UNKNOWN = '<unknown>'

def __init__(
self,
type,
repo,
name=None,
rev='master',
link=None,
scripts=None,
sparse_paths=None,
):
def __post_init__(self):
if self.name is None:
self.name = self._infer_name(self.repo)

super().__init__()
self.type = type or 'git'
self.repo = repo
self.name = self._infer_name(repo) if name is None else name
self.rev = rev
self.link = link
self.scripts = scripts or []
self.sparse_paths = sparse_paths or []

for key in ['name', 'repo', 'rev']:
if not self[key]:
msg = "'{}' required for {}".format(key, repr(self))
# TODO: Remove this?
for name in ['name', 'repo', 'rev']:
if not getattr(self, name):
msg = "'{}' required for {}".format(name, repr(self))
raise exceptions.InvalidConfig(msg)

def _on_post_load(self):
# TODO: Remove this?
self.type = self.type or 'git'

def __repr__(self):
Expand Down Expand Up @@ -80,6 +68,7 @@ def update_files(
log.info("Updating source files...")

# Clone the repository if needed
assert self.name
if not os.path.exists(self.name):
git.clone(
self.type,
Expand Down Expand Up @@ -178,7 +167,7 @@ def run_scripts(self, force=False):
raise self._invalid_repository

# Check for scripts
if not self.scripts:
if not self.scripts or not self.scripts[0]:
common.show("(no scripts to run)", color='shell_info')
common.newline()
return
Expand All @@ -201,6 +190,7 @@ def run_scripts(self, force=False):

def identify(self, allow_dirty=True, allow_missing=True, skip_changes=False):
"""Get the path and current repository URL and hash."""
assert self.name
if os.path.isdir(self.name):

shell.cd(self.name)
Expand Down Expand Up @@ -257,18 +247,19 @@ def lock(self, rev=None, allow_dirty=False, skip_changes=False):
return None

source = self.__class__(
self.type,
self.repo,
self.name,
rev,
self.link,
self.scripts,
self.sparse_paths,
type=self.type,
repo=self.repo,
name=self.name,
rev=rev,
link=self.link,
scripts=self.scripts,
sparse_paths=self.sparse_paths,
)
return source

@property
def _invalid_repository(self):
assert self.name
path = os.path.join(os.getcwd(), self.name)
msg = """

Expand Down
8 changes: 4 additions & 4 deletions gitman/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@

import os

import datafiles
import log


# Serialization settings
datafiles.settings.INDENT_YAML_BLOCKS = False

# Cache settings
CACHE = os.path.expanduser(os.getenv('GITMAN_CACHE', "~/.gitcache"))
CACHE_DISABLE = bool(os.getenv('GITMAN_CACHE_DISABLE'))
Expand All @@ -19,7 +23,3 @@
VERBOSE_LOGGING_LEVEL = log.INFO
VERBOSE2_LOGGING_LEVEL = log.DEBUG
LOGGING_DATEFMT = "%Y-%m-%d %H:%M"

# 3rd party settings
YORM_LOGGING_LEVEL = log.WARNING
SH_LOGGING_LEVEL = log.WARNING
2 changes: 1 addition & 1 deletion gitman/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def call(name, *args, _show=True, _shell=False, _ignore=False):
"""
program = show(name, *args, stdout=_show)

command = subprocess.run(
command = subprocess.run( # pylint: disable=subprocess-run-check
name if _shell else [name, *args],
universal_newlines=True,
stdout=subprocess.PIPE,
Expand Down
11 changes: 7 additions & 4 deletions gitman/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

import os

import datafiles
import log
import pytest
import yorm


ENV = 'TEST_INTEGRATION' # environment variable to enable integration tests
Expand All @@ -16,14 +17,16 @@
def pytest_configure(config):
terminal = config.pluginmanager.getplugin('terminal')
terminal.TerminalReporter.showfspath = False
log.silence('gitman.shell', allow_info=True)
log.silence('datafiles', allow_warning=True)


def pytest_runtest_setup(item):
"""Disable YORM file storage during unit tests."""
"""Disable file storage during unit tests."""
if 'integration' in item.keywords:
if not os.getenv(ENV):
pytest.skip(REASON)
else:
yorm.settings.fake = False
datafiles.settings.HOOKS_ENABLED = True
else:
yorm.settings.fake = True
datafiles.settings.HOOKS_ENABLED = False
Loading