Skip to content

Commit

Permalink
Allow for filepaths to include (oras-project#161)
Browse files Browse the repository at this point in the history
* Allow for filepaths to include

When playing with omlmd I tried to push a file which contained a ":" and
oras choked on it. I belive that you should check if the file exists and
only split off the last : looking for options, not the first colon.

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Signed-off-by: tarilabs <matteo.mortari@gmail.com>
  • Loading branch information
rhatdan authored Oct 9, 2024
1 parent 8f52216 commit 66d57d3
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ and **Merged pull requests**. Critical items to know are:
The versions coincide with releases on pip. Only major versions will be released as tags on Github.

## [0.0.x](https://github.com/oras-project/oras-py/tree/main) (0.0.x)
- allow for filepaths to include `:` (0.2.22)
- release request (0.2.21)
- add missing basic auth data for request token function in token auth backend (0.2.2)
- re-enable chunked upload (0.2.1)
Expand Down
65 changes: 59 additions & 6 deletions oras/tests/test_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,65 @@ def test_annotated_registry_push(tmp_path, registry, credentials, target):
)


@pytest.mark.with_auth(False)
def test_file_contains_column(tmp_path, registry, credentials, target):
"""
Test for file containing column symbol
"""
client = oras.client.OrasClient(hostname=registry, insecure=True)
artifact = os.path.join(here, "artifact.txt")
assert os.path.exists(artifact)

# file containing `:`
try:
contains_column = here / "some:file"
with open(contains_column, "w") as f:
f.write("hello world some:file")

res = client.push(files=[contains_column], target=target)
assert res.status_code in [200, 201]

files = client.pull(target, outdir=tmp_path / "download")
download = str(tmp_path / "download/some:file")
assert download in files
assert oras.utils.get_file_hash(
str(contains_column)
) == oras.utils.get_file_hash(download)
finally:
contains_column.unlink()

# file containing `:` as prefix, pushed with type
try:
contains_column = here / ":somefile"
with open(contains_column, "w") as f:
f.write("hello world :somefile")

res = client.push(files=[f"{contains_column}:text/plain"], target=target)
assert res.status_code in [200, 201]

files = client.pull(target, outdir=tmp_path / "download")
download = str(tmp_path / "download/:somefile")
assert download in files
assert oras.utils.get_file_hash(
str(contains_column)
) == oras.utils.get_file_hash(download)
finally:
contains_column.unlink()

# error: file does not exist
with pytest.raises(FileNotFoundError):
client.push(files=[".doesnotexist"], target=target)

with pytest.raises(FileNotFoundError):
client.push(files=[":doesnotexist"], target=target)

with pytest.raises(FileNotFoundError, match=r".*does:not:exists .*"):
client.push(files=["does:not:exists:text/plain"], target=target)

with pytest.raises(FileNotFoundError, match=r".*does:not:exists .*"):
client.push(files=["does:not:exists:text/plain+ext"], target=target)


@pytest.mark.with_auth(False)
def test_chunked_push(tmp_path, registry, credentials, target):
"""
Expand Down Expand Up @@ -130,12 +189,6 @@ def test_parse_manifest(registry):
assert ref == "path/to/config"
assert content_type == "application/vnd.oci.image.config.v1+json"

testref = "path/to/config:application/vnd.oci.image.config.v1+json:extra"
remote = oras.provider.Registry(hostname=registry, insecure=True)
ref, content_type = remote._parse_manifest_ref(testref)
assert ref == "path/to/config"
assert content_type == "application/vnd.oci.image.config.v1+json:extra"

testref = "/dev/null:application/vnd.oci.image.manifest.v1+json"
ref, content_type = remote._parse_manifest_ref(testref)
assert ref == "/dev/null"
Expand Down
5 changes: 3 additions & 2 deletions oras/utils/fileio.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ def split_path_and_content(ref: str) -> PathAndOptionalContent:
: return: A Tuple of the path in the reference, and the content-type if one found,
otherwise None.
"""
if ":" not in ref:

if os.path.exists(ref) or ":" not in ref:
return PathAndOptionalContent(ref, None)

if pathlib.Path(ref).drive:
Expand All @@ -370,5 +371,5 @@ def split_path_and_content(ref: str) -> PathAndOptionalContent:
)
return PathAndOptionalContent(ref, None)
else:
path_content_list = ref.split(":", 1)
path_content_list = ref.rsplit(":", 1)
return PathAndOptionalContent(path_content_list[0], path_content_list[1])
2 changes: 1 addition & 1 deletion oras/version.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
__copyright__ = "Copyright The ORAS Authors."
__license__ = "Apache-2.0"

__version__ = "0.2.21"
__version__ = "0.2.22"
AUTHOR = "Vanessa Sochat"
EMAIL = "vsoch@users.noreply.github.com"
NAME = "oras"
Expand Down

0 comments on commit 66d57d3

Please sign in to comment.