diff --git a/dockerfile_parse/parser.py b/dockerfile_parse/parser.py index 1fe07f0..e66de97 100644 --- a/dockerfile_parse/parser.py +++ b/dockerfile_parse/parser.py @@ -9,8 +9,8 @@ import json import logging -import os import re +from pathlib import Path from contextlib import contextmanager from shlex import quote @@ -85,7 +85,8 @@ def __init__(self, path=None, env_replace=True, parent_env=None, fileobj=None, - build_args=None): + build_args=None, + dockerfile_filename=DOCKERFILE_FILENAME): """ Initialize source of Dockerfile :param path: path to (directory with) Dockerfile; if not provided, @@ -97,9 +98,12 @@ def __init__(self, path=None, :param fileobj: seekable file-like object containing Dockerfile content as bytes (will be truncated on write) :param build_args: python dict of build args used when building image + :param dockerfile_filename: name of the dockerfile to discover or create + in the path (default: Dockerfile) """ self.fileobj = fileobj + self.dockerfile = None if self.fileobj is not None: if path is not None: @@ -107,11 +111,11 @@ def __init__(self, path=None, else: self.fileobj.seek(0) else: - path = path or '.' - if path.endswith(DOCKERFILE_FILENAME): - self.dockerfile_path = path + path = Path(path) or Path.cwd() + if path.name.endswith(dockerfile_filename): + self.dockerfile = path else: - self.dockerfile_path = os.path.join(path, DOCKERFILE_FILENAME) + self.dockerfile = path / dockerfile_filename self.cache_content = cache_content self.cached_content = '' # unicode string @@ -149,9 +153,20 @@ def _open_dockerfile(self, mode): yield self.fileobj self.fileobj.seek(0) else: - with open(self.dockerfile_path, mode) as dockerfile: + with self.dockerfile.open(mode) as dockerfile: yield dockerfile + @property + def dockerfile_path(self): + """ + :return: Path to the Dockerfile as a string, or None if using fileobj + """ + return str(self.dockerfile) if self.dockerfile else None + + @dockerfile_path.setter + def dockerfile_path(self, value): + self.dockerfile = Path(value) if value else None + @property def lines(self): """ diff --git a/tests/test_parser.py b/tests/test_parser.py index cc9b010..2fd8915 100644 --- a/tests/test_parser.py +++ b/tests/test_parser.py @@ -14,6 +14,7 @@ import pytest import re import sys +from pathlib import Path from textwrap import dedent from dockerfile_parse import DockerfileParser @@ -1509,3 +1510,30 @@ def test_escape_directive_ignore_after_comment(self, dfparser): 'value': 'touch foo; touch bar' } ] + + def test_alt_dockerfile_names(self, tmpdir): + tmpdir = Path(tmpdir) + content = "FROM fedora:38" + out = DockerfileParser(path=tmpdir, dockerfile_filename="Containerfile") + out.content = content + + assert out.dockerfile == tmpdir / "Containerfile" + assert out.dockerfile.is_file() + + validate = DockerfileParser(path=tmpdir, dockerfile_filename="Containerfile") + assert validate.baseimage == out.baseimage + + def test_dockerfile_path_compatibility(self, tmpdir): + tmpdir = Path(tmpdir) + parser = DockerfileParser(path=tmpdir) + assert str(parser.dockerfile) == parser.dockerfile_path + assert parser.dockerfile == tmpdir / "Dockerfile" + + with (tmpdir / "nothing").open("w+") as testfile: + nullparser = DockerfileParser(fileobj=testfile) + assert nullparser.dockerfile is None + assert nullparser.dockerfile_path is None + + newfile = tmpdir / "nowhere" + parser.dockerfile_path = str(newfile) + assert parser.dockerfile == newfile