Skip to content

Commit

Permalink
Merge pull request #281 from vidartf/add-diff-driver-args
Browse files Browse the repository at this point in the history
Use diff args for git diff driver
  • Loading branch information
minrk authored Apr 18, 2017
2 parents 1dbc671 + 99109dd commit c8f5544
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 58 deletions.
5 changes: 3 additions & 2 deletions nbdime/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,10 @@ def add_diff_args(parser):
help="process/ignore metadata.")



diff_exclusives = ('sources', 'outputs', 'attachments', 'metadata')
def process_diff_flags(args):
exclusives = ('sources', 'outputs', 'attachments', 'metadata')
process_exclusive_ignorables(args, exclusives)
process_exclusive_ignorables(args, diff_exclusives)
set_notebook_diff_targets(args.sources, args.outputs,
args.attachments, args.metadata)

Expand Down
7 changes: 5 additions & 2 deletions nbdime/gitdiffdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
from subprocess import check_call, CalledProcessError

from . import nbdiffapp
from .args import add_git_config_subcommand
from .args import add_git_config_subcommand, add_diff_args, diff_exclusives
from .utils import locate_gitattributes, ensure_dir_exists


Expand Down Expand Up @@ -77,6 +77,7 @@ def main(args=None):
diff_parser = subparsers.add_parser('diff',
description="The actual entrypoint for the diff tool. Git will call this."
)
add_diff_args(diff_parser)
# Argument list
# path old-file old-hex old-mode new-file new-hex new-mode [ rename-to ]
diff_parser.add_argument('path')
Expand All @@ -97,7 +98,9 @@ def main(args=None):

opts = parser.parse_args(args)
if opts.subcommand == 'diff':
return nbdiffapp.main([opts.a, opts.b])
return nbdiffapp.main(
[opts.a, opts.b] +
['--%s' % name for name in diff_exclusives if getattr(opts, name)])
elif opts.subcommand == 'config':
opts.config_func(opts.scope)
return 0
Expand Down
14 changes: 12 additions & 2 deletions nbdime/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@

from jsonschema import Draft4Validator as Validator
from jsonschema import RefResolver
from pytest import yield_fixture, fixture, skip
from pytest import fixture, skip
import nbformat

from .utils import call, have_git

from nbdime.webapp.nbdimeserver import init_app
from nbdime.diffing.notebooks import set_notebook_diff_targets

pjoin = os.path.join

Expand Down Expand Up @@ -149,7 +150,7 @@ def git_repo2(tmpdir, request, filespath, needs_git):
return repo


@yield_fixture
@fixture
def reset_log():
# clear root logger handlers before test and reset afterwards
handlers = list(logging.getLogger().handlers)
Expand Down Expand Up @@ -323,3 +324,12 @@ def unique_port():
global _port
_port += 1
return _port


@fixture()
def reset_diff_targets():
try:
yield
finally:
# Reset diff targets (global variable)
set_notebook_diff_targets()
8 changes: 4 additions & 4 deletions nbdime/tests/test_cli_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def test_nbdiff_app_unicode_safe(filespath):
check_call([sys.executable, '-m', 'nbdime.nbdiffapp', afn, bfn], env=env)


def test_nbdiff_app_only_source(filespath, tmpdir):
def test_nbdiff_app_only_source(filespath, tmpdir, reset_diff_targets):
afn = os.path.join(filespath, "multilevel-test-base.ipynb")
bfn = os.path.join(filespath, "multilevel-test-local.ipynb")
dfn = os.path.join(tmpdir.dirname, "diff_output.json")
Expand All @@ -122,7 +122,7 @@ def test_nbdiff_app_only_source(filespath, tmpdir):
diff = diff[0]['diff']


def test_nbdiff_app_ignore_source(filespath, tmpdir):
def test_nbdiff_app_ignore_source(filespath, tmpdir, reset_diff_targets):
afn = os.path.join(filespath, "multilevel-test-base.ipynb")
bfn = os.path.join(filespath, "multilevel-test-local.ipynb")
dfn = os.path.join(tmpdir.dirname, "diff_output.json")
Expand Down Expand Up @@ -439,7 +439,7 @@ def _wait_up(url, interval=0.1, check=None):
break


@pytest.mark.timeout(timeout=WEB_TEST_TIMEOUT)
@pytest.mark.timeout(timeout=3*WEB_TEST_TIMEOUT)
def test_difftool(git_repo, request, unique_port):
nbdime.gitdifftool.main(['config', '--enable'])
cmd = get_output('git config --get --local difftool.nbdime.cmd').strip()
Expand Down Expand Up @@ -478,7 +478,7 @@ def _term():
assert process.poll() == 0


@pytest.mark.timeout(timeout=WEB_TEST_TIMEOUT)
@pytest.mark.timeout(timeout=3*WEB_TEST_TIMEOUT)
def test_mergetool(git_repo, request, unique_port):
nbdime.gitmergetool.main(['config', '--enable'])
cmd = get_output('git config --get --local mergetool.nbdime.cmd').strip()
Expand Down
43 changes: 43 additions & 0 deletions nbdime/tests/test_git_diffdriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,27 @@
"""

expected_source_only = """nbdiff {0} {1}
--- {0} {2}
+++ {1} {3}
## modified /cells/0/source:
@@ -1,3 +1,3 @@
-def foe(x, y):
+def foo(x, y):
return x + y
-foe(3, 2)
+foo(1, 2)
## modified /cells/1/source:
@@ -1,3 +1,3 @@
-def foo(x, y):
+def foe(x, y):
return x * y
-foo(1, 2)
+foe(1, 2)
"""


def test_git_diff_driver(capsys, nocolor, needs_git):
# Simulate a call from `git diff` to check basic driver functionality
Expand All @@ -60,3 +81,25 @@ def test_git_diff_driver(capsys, nocolor, needs_git):
assert r == 0
cap_out = capsys.readouterr()[0]
assert cap_out == expected_output.format(fn1, fn2, t1, t2)


def test_git_diff_driver_flags(capsys, nocolor, needs_git, reset_diff_targets):
# Simulate a call from `git diff` to check basic driver functionality
test_dir = os.path.abspath(os.path.dirname(__file__))

fn1 = pjoin(test_dir, 'files/foo--1.ipynb')
fn2 = pjoin(test_dir, 'files/foo--2.ipynb')
t1 = file_timestamp(fn1)
t2 = file_timestamp(fn2)

mock_argv = [
'/mock/path/git-nbdiffdriver', 'diff', '-s',
fn1,
fn1, 'invalid_mock_checksum', '100644',
fn2, 'invalid_mock_checksum', '100644']

with mock.patch('sys.argv', mock_argv):
r = gdd_main()
assert r == 0
cap_out = capsys.readouterr()[0]
assert cap_out == expected_source_only.format(fn1, fn2, t1, t2)
92 changes: 44 additions & 48 deletions nbdime/tests/test_merge_notebooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ def _check(partial, expected_partial, decisions, expected_conflicts):
for e, d in zip(expected_conflicts, conflicts):
# Only check keys specified in expectation value
for k in sorted(e.keys()):
#if d[k] != e[k]: import ipdb; ipdb.set_trace()
assert d[k] == e[k]


Expand Down Expand Up @@ -892,64 +891,61 @@ def test_autoresolve_empty_strategies():
_check(partial, expected_partial, decisions, expected_conflicts)


class TestMergeDiffIgnores:
def test_only_sources(db, reset_diff_targets):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(True, False, False, False)

def teardown(self):
set_notebook_diff_targets(True, True, True, True)
merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"

def test_only_sources(self, db):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(True, False, False, False)
partial, decisions = merge_notebooks(base, local, remote, merge_args)

merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"
assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert len(path) == 2 or path[2] == 'source'

partial, decisions = merge_notebooks(base, local, remote, merge_args)

assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert len(path) == 2 or path[2] == 'source'
def test_only_outputs(db, reset_diff_targets):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(False, True, False, False)

def test_only_outputs(self, db):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(False, True, False, False)
merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"

merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"
partial, decisions = merge_notebooks(base, local, remote, merge_args)

partial, decisions = merge_notebooks(base, local, remote, merge_args)
assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert len(path) == 2 or path[2] == 'outputs'

assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert len(path) == 2 or path[2] == 'outputs'

def test_only_metadata(self, db):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(False, False, False, True)
def test_only_metadata(db, reset_diff_targets):
base = db["mixed-conflicts--1"]
local = db["mixed-conflicts--2"]
remote = db["mixed-conflicts--3"]
set_notebook_diff_targets(False, False, False, True)

merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"
merge_args = copy.deepcopy(args)
merge_args.merge_strategy = "mergetool"

partial, decisions = merge_notebooks(base, local, remote, merge_args)
partial, decisions = merge_notebooks(base, local, remote, merge_args)

assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert (
len(path) == 2 or
path[0] == 'metadata' or
path[2] == 'metadata' or
path[4] == 'metadata'
)
assert len(decisions) > 0
for d in decisions:
path = d['common_path']
# Still have some decisions on cell root, so avoid with len == 2 check
assert (
len(path) == 2 or
path[0] == 'metadata' or
path[2] == 'metadata' or
path[4] == 'metadata'
)

1 change: 1 addition & 0 deletions nbdime/webapp/nbdimeserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def init_app(on_port=None, closable=False, **params):
app = make_app(**params)
if port != 0 or on_port is None:
app.listen(port, address=ip)
_logger.info('Listening on %s, port %d' % (ip, port))
else:
sockets = netutil.bind_sockets(0, ip)
server = httpserver.HTTPServer(app)
Expand Down

0 comments on commit c8f5544

Please sign in to comment.