Skip to content

Commit

Permalink
Improve merge widgets (jupyterlab#1031)
Browse files Browse the repository at this point in the history
* Improve merge widgets

* Fix get base content

* Improve style of conflicted files

* Improve styles for merge raw file

* Pass translator to diff widget

* Improve style for notebook merge

* Hide drag handles

* Clean revert button styles

* Move checkboxes in toolbar

* Fix collapse unchanged cells in merge view

* Fix unit tests

* Display unmerged files separately in simple mode

* Add test for content base

* Less setup info duplication

* Update class name

* [skip ci] Remove commented line
  • Loading branch information
fcollonval authored Oct 8, 2021
1 parent b4590f8 commit e670239
Show file tree
Hide file tree
Showing 25 changed files with 552 additions and 165 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ jobs:
run: |
jlpm
jlpm run eslint:check
python -m pip install -e .[dev,tests]
python -m pip install -e .[tests]
# Python formatting checks
black . --check
Expand All @@ -82,8 +82,6 @@ jobs:
jupyter labextension list 2>&1 | grep -ie "@jupyterlab/git.*OK"
python -m jupyterlab.browser_check
# Run our extension-specific browser integration test
# python tests/test-browser/run_browser_test.py
- uses: actions/upload-artifact@v2
if: matrix.python-version == '3.9'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install jupyter_packaging~=0.7.9 jupyterlab~=3.0 packaging setuptools twine wheel
pip install jupyter_packaging~=0.7.9 jupyterlab~=3.0 packaging setuptools twine build
- name: Publish the Python package
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
python setup.py sdist bdist_wheel
python -m build
twine upload dist/*
- name: Publish the NPM package
run: |
Expand Down
46 changes: 40 additions & 6 deletions jupyterlab_git/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
import pexpect
import tornado
import tornado.locks
from nbdime import diff_notebooks, merge_notebooks
from jupyter_server.utils import ensure_async
from nbdime import diff_notebooks, merge_notebooks

from .log import get_logger

Expand Down Expand Up @@ -1219,11 +1219,41 @@ async def _get_tag(self, path, commit_sha):
)
)

async def show(self, filename, ref, path):
async def _get_base_ref(self, path, filename):
"""Get the object reference for an unmerged ``filename`` at base stage.
Execute git ls-files -u -z <filename>
Returns:
The object reference or None
"""
command = ["git", "ls-files", "-u", "-z", filename]

code, output, error = await execute(command, cwd=path)
if code != 0:
raise subprocess.CalledProcessError(
code, " ".join(command), output=output, stderr=error
)

split_line = strip_and_split(output)[0].split()

return split_line[1] if len(split_line) > 1 else None

async def show(self, path, ref, filename=None):
"""
Execute git show <ref:filename> command & return the result.
Execute
git show <ref:filename>
Or
git show <ref>
Return the file content
"""
command = ["git", "show", "{}:{}".format(ref, filename)]
command = ["git", "show"]

if filename is None:
command.append(ref)
else:
command.append(f"{ref}:{filename}")

code, output, error = await execute(command, cwd=path)

Expand Down Expand Up @@ -1286,7 +1316,11 @@ async def get_content_at_reference(
log_message="Error occurred while executing command to retrieve plaintext content as file is not UTF-8."
)

content = await self.show(filename, "", path)
content = await self.show(path, "", filename)
elif reference["special"] == "BASE":
# Special case of file in merge conflict for which we want the base (aka common ancestor) version
ref = await self._get_base_ref(path, filename)
content = await self.show(path, ref)
else:
raise tornado.web.HTTPError(
log_message="Error while retrieving plaintext content, unknown special ref '{}'.".format(
Expand All @@ -1300,7 +1334,7 @@ async def get_content_at_reference(
log_message="Error occurred while executing command to retrieve plaintext content as file is not UTF-8."
)

content = await self.show(filename, reference["git"], path)
content = await self.show(path, reference["git"], filename)
else:
content = ""

Expand Down
44 changes: 44 additions & 0 deletions jupyterlab_git/tests/test_handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,50 @@ async def test_content_index(mock_execute, jp_fetch, jp_root_dir):
)


@patch("jupyterlab_git.git.execute")
async def test_content_base(mock_execute, jp_fetch, jp_root_dir):
# Given
local_path = jp_root_dir / "test_path"
filename = "my/file"
content = "dummy content file\nwith multiple lines"
obj_ref = "915bb14609daab65e5304e59d89c626283ae49fc"

mock_execute.side_effect = [
maybe_future(
(
0,
"100644 {1} 1 {0}\x00100644 285bdbc14e499b85ec407512a3bb3992fa3d4082 2 {0}\x00100644 66ac842dfb0b5c20f757111d6b3edd56d80622b4 3 {0}\x00".format(
filename, obj_ref
),
"",
)
),
maybe_future((0, content, "")),
]

# When
body = {
"filename": filename,
"reference": {"special": "BASE"},
}
response = await jp_fetch(
NAMESPACE, local_path.name, "content", body=json.dumps(body), method="POST"
)

# Then
assert response.code == 200
payload = json.loads(response.body)
assert payload["content"] == content
mock_execute.assert_has_calls(
[
call(
["git", "show", obj_ref],
cwd=str(local_path),
),
],
)


@patch("jupyterlab_git.git.execute")
async def test_content_unknown_special(mock_execute, jp_fetch, jp_root_dir):
# Given
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
"license": "BSD-3-Clause",
"author": "Jupyter Development Team",
"keywords": [
"jupyter",
"jupyterlab",
"jupyterlab-extension"
"Jupyter",
"JupyterLab",
"JupyterLab3",
"jupyterlab-extension",
"Git"
],
"scripts": {
"build": "jlpm run build:lib && jlpm run build:labextension:dev",
Expand Down
47 changes: 47 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
[metadata]
long_description = file: README.md
long_description_content_type = text/markdown
platforms = Linux, Mac OS X, Windows
classifiers =
Intended Audience :: Developers
Intended Audience :: Science/Research
License :: OSI Approved :: BSD License
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Framework :: Jupyter
Framework :: Jupyter :: JupyterLab
Framework :: Jupyter :: JupyterLab :: 3
Framework :: Jupyter :: JupyterLab :: Extensions
Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt

[options]
packages = find:
install_requires =
jupyter_server
nbdime~=3.1
nbformat
packaging
pexpect
include_package_data = True
zip_safe = False
python_requires = >=3.6,<4

[options.extras_require]
dev=
black
coverage
jupyter_packaging~=0.7.9
jupyterlab~=3.0
pre-commit
pytest
pytest-asyncio
pytest-cov
pytest-tornasync
tests=
%(dev)s
hybridcontents

61 changes: 8 additions & 53 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
# The name of the project
name = "jupyterlab_git"

# Get our version
with (HERE / "package.json").open() as f:
version = str(parse(json.load(f)["version"]))
npm_data = json.load(f)
# Get the version
version = str(parse(npm_data["version"]))

lab_path = HERE / name / "labextension"

Expand Down Expand Up @@ -64,61 +65,15 @@
else:
cmdclass["jsdeps"] = skip_if_exists(jstargets, js_command)

long_description = (HERE / "README.md").read_text(errors="ignore")

setup_args = dict(
name=name,
version=version,
url="https://github.com/jupyterlab/jupyterlab-git.git",
author="Jupyter Development Team",
description="A JupyterLab extension for version control using git",
long_description=long_description,
long_description_content_type="text/markdown",
url=npm_data["homepage"],
author=npm_data["author"],
description=npm_data["description"],
cmdclass=cmdclass,
packages=setuptools.find_packages(),
install_requires=[
"jupyter_server",
"nbdime~=3.1",
"nbformat",
"packaging",
"pexpect",
],
zip_safe=False,
include_package_data=True,
python_requires=">=3.6,<4",
license="BSD-3-Clause",
platforms="Linux, Mac OS X, Windows",
keywords=["Jupyter", "JupyterLab", "JupyterLab3", "Git"],
classifiers=[
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: BSD License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.6",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Framework :: Jupyter",
"Framework :: Jupyter :: JupyterLab",
"Framework :: Jupyter :: JupyterLab :: 3",
"Framework :: Jupyter :: JupyterLab :: Extensions",
"Framework :: Jupyter :: JupyterLab :: Extensions :: Prebuilt",
],
extras_require={
"dev": [
"black",
"coverage",
"jupyter_packaging~=0.7.9",
"jupyterlab~=3.0",
"pre-commit",
"pytest",
"pytest-asyncio",
"pytest-cov",
"pytest-tornasync",
],
"tests": ["hybridcontents"],
},
license=npm_data["license"],
keywords=npm_data["keywords"],
)


Expand Down
Loading

0 comments on commit e670239

Please sign in to comment.