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
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Here you can find the recent changes to vcspull

current
-------
- :issue:`231` Add updating / merging of remote URLs (via PR :issue:`231`)
- Fix colorama constraint
- poetry lockfile: Fix (accidentally pushed lockfile via prerelease
version of poetry)
Expand Down
6 changes: 3 additions & 3 deletions poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ authors = ["Tony Narlock <tony@git-pull.com>"]
python = "~2.7 || ^3.5"
click = ">=7<8"
kaptan = "*"
libvcs = "==0.3.1post1"
libvcs = "==0.3.2"
colorama = ">=0.3.9"

[tool.poetry.dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion requirements/base.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kaptan>=0.5.9,<1
click>=7<8
colorama>=0.3.9
libvcs>=0.3.0,<0.4.0
libvcs>=0.3.2,<0.4.0
25 changes: 15 additions & 10 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,22 @@ def git_repo(git_repo_kwargs):


@pytest.fixture
def git_dummy_repo_dir(tmpdir_repoparent, scope='session'):
"""Create a git repo with 1 commit, used as a remote."""
name = 'dummyrepo'
repo_path = str(tmpdir_repoparent.join(name))
def create_git_dummy_repo(tmpdir_repoparent):
def fn(repo_name, testfile_filename='testfile.test'):
repo_path = str(tmpdir_repoparent.join(repo_name))

run(['git', 'init', repo_name], cwd=str(tmpdir_repoparent))

run(['touch', testfile_filename], cwd=repo_path)
run(['git', 'add', testfile_filename], cwd=repo_path)
run(['git', 'commit', '-m', 'test file for %s' % repo_name], cwd=repo_path)

run(['git', 'init', name], cwd=str(tmpdir_repoparent))
return repo_path

testfile_filename = 'testfile.test'
yield fn

run(['touch', testfile_filename], cwd=repo_path)
run(['git', 'add', testfile_filename], cwd=repo_path)
run(['git', 'commit', '-m', 'test file for %s' % name], cwd=repo_path)

return repo_path
@pytest.fixture
def git_dummy_repo_dir(tmpdir_repoparent, create_git_dummy_repo):
"""Create a git repo with 1 commit, used as a remote."""
return create_git_dummy_repo('dummyrepo')
40 changes: 39 additions & 1 deletion tests/test_repo_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@

from libvcs import BaseRepo, GitRepo, MercurialRepo, SubversionRepo
from libvcs.shortcuts import create_repo_from_pip_url
from vcspull.config import extract_repos, filter_repos
from vcspull.cli import update_repo
from vcspull.config import extract_repos, filter_repos, load_configs

from .fixtures import example as fixtures

Expand Down Expand Up @@ -141,3 +142,40 @@ def test_makes_recursive(tmpdir, git_dummy_repo_dir):
for r in filter_repos(repos):
repo = create_repo_from_pip_url(**r)
repo.obtain()


def test_updating_remote(tmpdir, create_git_dummy_repo):
"""Ensure that directories in pull are made recursively."""

def create_and_load_configs(repo_name):
dummy_repo = create_git_dummy_repo(repo_name)

YAML_CONFIG = """
{TMP_DIR}/study/myrepo:
my_url: git+file://{REPO_DIR}
"""

YAML_CONFIG = YAML_CONFIG.format(TMP_DIR=str(tmpdir), REPO_DIR=dummy_repo)
CONFIG_FILENAME = 'myrepos.yaml'
config_file = tmpdir.join(CONFIG_FILENAME)
config_file.write(YAML_CONFIG)
repo_parent = tmpdir.join('study/myrepo')
repo_parent.ensure(dir=True)
return config_file

config_file = create_and_load_configs('dummyrepo')
configs = load_configs([str(config_file)])

for repo_dict in filter_repos(configs, repo_dir='*', vcs_url='*', name='*'):
old_repo_remotes = update_repo(repo_dict).remotes_get['origin']

# Later: Copy dummy repo somewhere else so the commits are common
config_file = create_and_load_configs('new_repo_url')
configs = load_configs([str(config_file)])

for repo_dict in filter_repos(configs, repo_dir='*', vcs_url='*', name='*'):
repo_url = repo_dict['url'].replace('git+', '')
r = update_repo(repo_dict)
current_remote_url = r.remotes_get['origin']
assert current_remote_url[0] == repo_url
assert current_remote_url != old_repo_remotes
38 changes: 34 additions & 4 deletions vcspull/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@

import logging
import sys
from copy import deepcopy

import click

from libvcs._compat import PY2
from libvcs.shortcuts import create_repo_from_pip_url

from .__about__ import __version__
from .cli_defaultgroup import DefaultGroup
from .config import filter_repos, find_config_files, load_configs
from .log import DebugLogFormatter, RepoFilter, RepoLogFormatter

if PY2:
FileNotFoundError = EnvironmentError

MIN_ASYNC = 3 # minimum amount of repos to sync concurrently
MAX_ASYNC = 8 # maximum processes to open:w

Expand Down Expand Up @@ -122,12 +127,37 @@ def progress_cb(output, timestamp):


def update_repo(repo_dict):
repo_dict['pip_url'] = repo_dict.pop('url')
repo_dict = deepcopy(repo_dict)
if 'pip_url' not in repo_dict:
repo_dict['pip_url'] = repo_dict.pop('url')
repo_dict['progress_callback'] = progress_cb

r = create_repo_from_pip_url(**repo_dict)

r.update_repo()
r = create_repo_from_pip_url(**repo_dict) # Creates the repo object

remote_settings = repo_dict.get('remotes', [])
if not any(rs for rs in remote_settings if rs['remote_name'] == 'origin'):
remote_settings.append({'remote_name': 'origin', 'url': repo_dict['pip_url']})

for remote_setting in remote_settings:
config_remote_name = remote_setting['remote_name'] # From config file
try:
current_remote = r.remotes_get.get(config_remote_name)
except FileNotFoundError: # git repo doesn't exist yet, so cna't be outdated
break

if current_remote is not None and current_remote[0] != remote_setting['url']:
print(
'Updating remote {name} ({current_url}) with {new_url}'.format(
name=config_remote_name,
current_url=current_remote[0],
new_url=remote_setting['url'],
)
)
r.remote_set(
name=config_remote_name, url=remote_setting['url'], overwrite=True
)
r.update_repo() # Creates repo if not exists and fetches
return r


cli.add_command(update)