Skip to content
Open
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
19 changes: 19 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
environment:

matrix:
- PYTHON: "C:\\Python36"
# - PYTHON: "C:\\Python37"

build: off

install:
- "%PYTHON%\\python.exe -m pip install -r requirements.txt"
- "%PYTHON%\\python.exe setup.py install"

test_script:
- "%PYTHON%\\python.exe setup.py test"

branches:
only:
- master
- /release-v[0-9]+/
18 changes: 17 additions & 1 deletion arca/_arca.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import hashlib
import json
import platform
import re
from collections import defaultdict
from datetime import datetime
Expand Down Expand Up @@ -139,7 +140,22 @@ def validate_repo_url(self, repo: str):
:raise ValueError: If the URL is not valid
"""
# that should match valid git repos
if not isinstance(repo, str) or not re.match(r"^(https?|file)://[\w._\-/~]*[.git]?/?$", repo):
valid = True

url_regex = re.compile(r"^https?://[\w._\-/~]*[.git]?/?$")

if not isinstance(repo, str):
valid = False
else:
if platform.system() == "Windows":
if not url_regex.match(repo) and not re.match(r"file://(localhost)?/[a-zA-Z]:\\[\\\S|*\S]?.*", repo):
valid = False

else:
if not url_regex.match(repo) and not re.match(r"file://[\w._\-/~]*[.git]?/?$", repo):
valid = False

if not valid:
raise ValueError(f"{repo} is not a valid http[s] or file:// git repository.")

def repo_id(self, repo: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
gitpython
pytest
dogpile.cache==0.6.5
docker~=3.1.0
docker~=3.4.1
pytest-flake8
pytest-cov
pytest-mock
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,10 @@ def long_description():
],
extras_require={
"docker": [
"docker~=3.2.1",
"docker~=3.4.1",
],
"vagrant": [
"docker~=3.2.1",
"docker~=3.4.1",
"python-vagrant",
"fabric3",
],
Expand Down
4 changes: 3 additions & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import os

from pathlib import Path

if os.environ.get("TRAVIS", False):
BASE_DIR = "/home/travis/build/{}/test_loc".format(os.environ.get("TRAVIS_REPO_SLUG", "mikicz/arca"))
elif os.environ.get("APPVEYOR", False):
BASE_DIR = str(Path(os.environ["APPVEYOR_BUILD_FOLDER"]) / "test_loc")
else:
BASE_DIR = "/tmp/arca/test"

Expand Down
10 changes: 9 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import platform
import shutil
import tempfile
from pathlib import Path
Expand All @@ -16,7 +17,12 @@ def create_temp_repo(file) -> TempRepo:
git_dir = Path(tempfile.mkdtemp())
repo = Repo.init(str(git_dir))

return TempRepo(repo, git_dir, f"file://{git_dir}", "master", git_dir / file)
file_url = f"file://{git_dir}"

if platform.system() == "Windows":
file_url = f"file:///{git_dir}"

return TempRepo(repo, git_dir, file_url, "master", git_dir / file)


@pytest.fixture()
Expand All @@ -30,6 +36,7 @@ def temp_repo_func():

yield temp_repo

temp_repo.repo.close()
shutil.rmtree(str(temp_repo.repo_path))


Expand All @@ -44,4 +51,5 @@ def temp_repo_static():

yield temp_repo

temp_repo.repo.close()
shutil.rmtree(str(temp_repo.repo_path))
43 changes: 34 additions & 9 deletions tests/test_arca_class.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# encoding=utf-8
import platform
import re
import shutil
from pathlib import Path
Expand Down Expand Up @@ -32,18 +33,33 @@ class NotASubclassClass:


@pytest.mark.parametrize(["url", "valid"], [
# http/s
("http://host.xz/path/to/repo.git/", True),
("https://host.xz/path/to/repo.git/", True),
("http://host.xz/path/to/repo.git", True),
("https://host.xz/path/to/repo.git", True),
("file:///path/to/repo.git/", True),
("file://~/path/to/repo.git/", True),
("http://host.xz/path/to/repo/", True),
("https://host.xz/path/to/repo/", True),
("http://host.xz/path/to/repo", True),
("https://host.xz/path/to/repo", True),
("file:///path/to/repo.git", True),
("file://~/path/to/repo.git", True),

# linux paths
pytest.param("file:///path/to/repo.git/", True,
marks=pytest.mark.skipif(platform.system() == "Windows", reason="Linux Path")),
pytest.param("file://~/path/to/repo.git/", True,
marks=pytest.mark.skipif(platform.system() == "Windows", reason="Linux Path")),
pytest.param("file:///path/to/repo.git", True,
marks=pytest.mark.skipif(platform.system() == "Windows", reason="Linux Path")),
pytest.param("file://~/path/to/repo.git", True,
marks=pytest.mark.skipif(platform.system() == "Windows", reason="Linux Path")),

# windows paths
pytest.param("file:///C:\\user\\path \\to\\repo", True,
marks=pytest.mark.skipif(platform.system() != "Windows", reason="Windows Path")),
pytest.param("file:///c:\\user\\path \\to\\repo", True,
marks=pytest.mark.skipif(platform.system() != "Windows", reason="Windows Path")),

# ssh
("git://host.xz/path/to/repo.git/", False),
("git://host.xz/~user/path/to/repo.git/", False),
("ssh://host.xz/path/to/repo.git/", False),
Expand Down Expand Up @@ -177,6 +193,7 @@ def test_depth(temp_repo_static):
cloned_repo, cloned_repo_path = arca.get_files(temp_repo_static.url, temp_repo_static.branch)
assert cloned_repo.commit().count() == 2

cloned_repo.close()
shutil.rmtree(str(cloned_repo_path))

# test that when setting a certain depth, at least the depth is pulled (in case of merges etc)
Expand All @@ -194,6 +211,7 @@ def test_depth(temp_repo_static):
cloned_repo, cloned_repo_path = arca.get_files(temp_repo_static.url, temp_repo_static.branch)
assert cloned_repo.commit().count() == before_second_pull + 1

cloned_repo.close()
shutil.rmtree(str(cloned_repo_path))

# test when setting depth bigger than repo size, no fictional commits are included
Expand All @@ -202,6 +220,7 @@ def test_depth(temp_repo_static):

assert cloned_repo.commit().count() == 22 # 20 plus the 2 extra commits

cloned_repo.close()
shutil.rmtree(str(cloned_repo_path))

# test no limit
Expand Down Expand Up @@ -237,7 +256,7 @@ def test_reference():
arca = Arca(base_dir=BASE_DIR)
branch = "master"

git_dir_1 = Path("/tmp/arca/") / str(uuid4())
git_dir_1 = Path(BASE_DIR) / str(uuid4())
git_url_1 = f"file://{git_dir_1}"
filepath_1 = git_dir_1 / "test_file.txt"
repo_1 = Repo.init(git_dir_1)
Expand All @@ -252,13 +271,15 @@ def test_reference():

# test nonexistent reference

cloned_repo, cloned_repo_path = arca.get_files(git_url_1, branch, reference=Path("/tmp/arca/") / str(uuid4()))
cloned_repo, cloned_repo_path = arca.get_files(git_url_1, branch, reference=Path(BASE_DIR) / str(uuid4()))
assert (cloned_repo_path / "test_file.txt").read_text() == last_uuid

cloned_repo.close()
shutil.rmtree(str(cloned_repo_path))

# test existing reference with no common commits

git_dir_2 = Path("/tmp/arca/") / str(uuid4())
git_dir_2 = Path(BASE_DIR) / str(uuid4())
filepath_2 = git_dir_2 / "test_file.txt"
repo_2 = Repo.init(git_dir_2)

Expand All @@ -269,11 +290,13 @@ def test_reference():

cloned_repo, cloned_repo_path = arca.get_files(git_url_1, branch, reference=git_dir_2)
assert (cloned_repo_path / "test_file.txt").read_text() == last_uuid

cloned_repo.close()
shutil.rmtree(str(cloned_repo_path))

# test existing reference with common commits

git_dir_3 = Path("/tmp/arca/") / str(uuid4())
git_dir_3 = Path(BASE_DIR) / str(uuid4())
git_url_3 = f"file://{git_dir_3}"
filepath_3 = git_dir_3 / "test_file.txt"
repo_3 = repo_1.clone(str(git_dir_3)) # must pass string, fails otherwise
Expand Down Expand Up @@ -334,7 +357,7 @@ def test_get_reference_repository(temp_repo_static):
def test_pull_error():
arca = Arca(base_dir=BASE_DIR)

git_dir = Path("/tmp/arca/") / str(uuid4())
git_dir = Path(BASE_DIR) / str(uuid4())
git_url = f"file://{git_dir}"

with pytest.raises(PullError):
Expand All @@ -351,6 +374,8 @@ def test_pull_error():
with pytest.raises(PullError):
arca.get_files(git_url, "some_branch")

repo.close()

shutil.rmtree(str(git_dir))

with pytest.raises(PullError):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def test_backends(temp_repo_func, backend, requirements_location, file_location)

assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "Some string"

filepath.write_text(SECOND_RETURN_STR_FUNCTION)
filepath.write_text(SECOND_RETURN_STR_FUNCTION, encoding="utf-8")
temp_repo_func.repo.create_head("new_branch")
temp_repo_func.repo.create_tag("test_tag")
temp_repo_func.repo.index.add([str(filepath)])
Expand Down
14 changes: 10 additions & 4 deletions tests/test_runner.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import json
import os
import tempfile
from pathlib import Path

Expand Down Expand Up @@ -35,7 +36,8 @@
"kwargs": [1, 2, 3]},
])
def test_definition_corruption(definition):
_, file = tempfile.mkstemp()
fd, file = tempfile.mkstemp()

file = Path(file)

if isinstance(definition, dict):
Expand All @@ -49,6 +51,7 @@ def test_definition_corruption(definition):
assert output["error"]
assert output["reason"] == "corrupted_definition"

os.close(fd)
file.unlink()


Expand All @@ -59,7 +62,7 @@ def test_definition_corruption(definition):
("arca", "Arca.some_random_method"),
])
def test_import_error(module_name, object_name):
_, file = tempfile.mkstemp()
fd, file = tempfile.mkstemp()
file = Path(file)

file.write_text(json.dumps({
Expand All @@ -74,6 +77,7 @@ def test_import_error(module_name, object_name):
assert output["error"]
assert output["reason"] == "import"

os.close(fd)
file.unlink()


Expand All @@ -86,7 +90,7 @@ def test_run(mocker, func, result):
load = mocker.patch("arca._runner.EntryPoint.load")
load.return_value = func

_, file = tempfile.mkstemp()
fd, file = tempfile.mkstemp()
file = Path(file)

file.write_text(json.dumps({
Expand All @@ -104,6 +108,7 @@ def test_run(mocker, func, result):
assert output["success"] is False
assert result.__name__ in output["error"]

os.close(fd)
file.unlink()


Expand All @@ -121,7 +126,7 @@ def func(カ):

load.return_value = func

_, file = tempfile.mkstemp()
fd, file = tempfile.mkstemp()
file = Path(file)

file.write_text(Task("library.mod:func", args=args, kwargs=kwargs).json)
Expand All @@ -130,6 +135,7 @@ def func(カ):

assert Result(output).output == result

os.close(fd)
file.unlink()


Expand Down
4 changes: 2 additions & 2 deletions tests/test_single_pull.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def test_single_pull(temp_repo_func, mocker):
assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "Some string"
assert arca._pull.call_count == 1

temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION)
temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION, encoding="utf-8")
temp_repo_func.repo.index.add([str(temp_repo_func.file_path)])
temp_repo_func.repo.index.commit("Updated function")

Expand All @@ -40,7 +40,7 @@ def test_pull_efficiency(temp_repo_func, mocker):
assert arca.run(temp_repo_func.url, temp_repo_func.branch, task).output == "Some string"
assert arca._pull.call_count == 2

temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION)
temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION, encoding="utf-8")
temp_repo_func.repo.index.add([str(temp_repo_func.file_path)])
temp_repo_func.repo.index.commit("Updated function")

Expand Down
8 changes: 4 additions & 4 deletions tests/test_vagrant.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@


def test_validation():
if os.environ.get("TRAVIS", False):
pytest.skip("Vagrant doesn't work on Travis")
if os.environ.get("CI", False):
pytest.skip("Vagrant doesn't work on CIs")

backend = VagrantBackend()

Expand Down Expand Up @@ -54,7 +54,7 @@ def test_validation():
# If you want to test that even init of the VM works, set ``destroy`` to True, it will destroy the previous one as well.
# Set to ``False`` by default to bootup time and bandwidth.
def test_vagrant(temp_repo_func, destroy=False):
if os.environ.get("TRAVIS", False):
if os.environ.get("CI", False):
pytest.skip("Vagrant doesn't work on Travis")

backend = VagrantBackend(verbosity=2, use_registry_name="docker.io/mikicz/arca-test",
Expand All @@ -78,7 +78,7 @@ def test_vagrant(temp_repo_func, destroy=False):
# branch branch - return unicode
temp_repo_func.repo.create_head("branch")
temp_repo_func.repo.branches.branch.checkout()
temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION)
temp_repo_func.file_path.write_text(SECOND_RETURN_STR_FUNCTION, encoding="utf-8")
temp_repo_func.repo.index.add([str(temp_repo_func.file_path)])
temp_repo_func.repo.index.commit("Test unicode on a separate branch")

Expand Down