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
50 changes: 37 additions & 13 deletions src/pyinfra/operations/files.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
from jinja2 import TemplateRuntimeError, TemplateSyntaxError, UndefinedError

from pyinfra import host, logger, state
from pyinfra.api.output import format_text
from pyinfra.api import (
FileDownloadCommand,
FileUploadCommand,
Expand All @@ -31,6 +30,7 @@
operation,
)
from pyinfra.api.command import make_formatted_string_command
from pyinfra.api.output import format_text
from pyinfra.api.util import (
get_call_location,
get_file_io,
Expand Down Expand Up @@ -1484,10 +1484,19 @@ def move(src: str, dest: str, overwrite=False):
"""

if host.get_fact(File, src) is None:
raise OperationError(f"src {src} does not exist")

if not host.get_fact(Directory, dest):
raise OperationError(f"dest {dest} is not an existing directory")
if state.is_executing:
raise OperationError(f"src {src} does not exist")
else:
logger.info(f"{host.print_prefix}src {src} does not exist yet")

dest_info = host.get_fact(Directory, dest)
if dest_info is False:
raise OperationError(f"dest {dest} is not a directory")
elif dest_info is None:
if state.is_executing:
raise OperationError(f"dest directory {dest} does not exist")
else:
logger.info(f"{host.print_prefix}dest directory {dest} does not exist yet")

full_dest_path = posixpath.join(dest, PurePosixPath(src).name)
if host.get_fact(File, full_dest_path) is not None:
Expand All @@ -1509,11 +1518,21 @@ def copy(src: str, dest: str, overwrite=False):
+ overwrite: whether to overwrite dest, if present
"""
src_is_dir = host.get_fact(Directory, src)
if not host.get_fact(File, src) and not src_is_dir:
raise OperationError(f"src {src} does not exist")

if not host.get_fact(Directory, dest):
raise OperationError(f"dest {dest} is not an existing directory")
src_is_file = host.get_fact(File, src)
if not src_is_file and not src_is_dir:
if state.is_executing:
raise OperationError(f"src {src} does not exist")
else:
logger.info(f"{host.print_prefix}src {src} does not exist yet")

dest_info = host.get_fact(Directory, dest)
if dest_info is False:
raise OperationError(f"dest {dest} is not a directory")
elif dest_info is None:
if state.is_executing:
raise OperationError(f"dest directory {dest} does not exist")
else:
logger.info(f"{host.print_prefix}dest directory {dest} does not exist yet")

dest_file_path = posixpath.join(dest, PurePosixPath(src).name)
dest_file_exists = host.get_fact(File, dest_file_path)
Expand Down Expand Up @@ -2255,9 +2274,14 @@ def unarchive(
yield FileUploadCommand(src, temp_archive)
archive_path = temp_archive
else:
# Validate the remote archive exists
if host.get_fact(File, path=src) is None:
raise OperationError(f"Remote archive {src} does not exist")
# Check if the remote archive exists
archive_info = host.get_fact(File, path=src)
if archive_info is False:
raise OperationError(f"Remote archive {src} is not a file")
elif archive_info is None:
if state.is_executing:
raise OperationError(f"Remote archive {src} does not exist")
logger.info(f"{host.print_prefix}Remote archive {src} does not exist")
archive_path = src

extras = list(extra_opts) if extra_opts else []
Expand Down
9 changes: 4 additions & 5 deletions tests/operations/files.copy/invalid_dest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@
},
"facts": {
"files.File": {
"path=/tmp/src_dir/file": true,
"path=/tmp/dest_dir/file": null
"path=/tmp/src_dir/file": true
},
"files.Directory": {
"path=/tmp/dest_dir": null,
"path=/tmp/src_dir/file": null
"path=/tmp/src_dir/file": false,
"path=/tmp/dest_dir": false
}
},
"exception": {
"name": "OperationError",
"message": "dest /tmp/dest_dir is not an existing directory"
"message": "dest /tmp/dest_dir is not a directory"
}
}
11 changes: 7 additions & 4 deletions tests/operations/files.copy/invalid_src.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
{
"require_platform": [
"Darwin",
"Linux"
],
"kwargs": {
"src": "/tmp/src_dir/file",
"dest": "/tmp/dest_dir",
Expand All @@ -14,8 +18,7 @@
"path=/tmp/src_dir/file": null
}
},
"exception": {
"name": "OperationError",
"message": "src /tmp/src_dir/file does not exist"
}
"commands": [
"cp -r /tmp/src_dir/file /tmp/dest_dir"
]
}
20 changes: 20 additions & 0 deletions tests/operations/files.copy/missing_dest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"kwargs": {
"src": "/tmp/src_dir/file",
"dest": "/tmp/dest_dir",
"overwrite": false
},
"facts": {
"files.File": {
"path=/tmp/src_dir/file": true,
"path=/tmp/dest_dir/file": null
},
"files.Directory": {
"path=/tmp/src_dir/file": false,
"path=/tmp/dest_dir": null
}
},
"commands": [
"cp -r /tmp/src_dir/file /tmp/dest_dir"
]
}
14 changes: 10 additions & 4 deletions tests/operations/files.move/invalid_dest.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
{
"require_platform": ["Darwin", "Linux"],
"args": ["tmp/testfile", "tmp2"],
"require_platform": [
"Darwin",
"Linux"
],
"args": [
"tmp/testfile",
"tmp2"
],
"facts": {
"files.File": {
"path=tmp/testfile": {
"mode": 600
}
},
"files.Directory": {
"path=tmp2": null
"path=tmp2": false
}
},
"exception": {
"name": "OperationError",
"message": "dest tmp2 is not an existing directory"
"message": "dest tmp2 is not a directory"
}
}
20 changes: 13 additions & 7 deletions tests/operations/files.move/invalid_src.json
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
{
"require_platform": ["Darwin", "Linux"],
"args": ["tmp/testfile", "tmp2"],
"require_platform": [
"Darwin",
"Linux"
],
"args": [
"tmp/testfile",
"tmp2"
],
"facts": {
"files.File": {
"path=tmp/testfile": null
"path=tmp/testfile": null,
"path=tmp2/testfile": null
},
"files.Directory": {
"path=tmp2": {
"mode": 700
}
}
},
"exception": {
"name": "OperationError",
"message": "src tmp/testfile does not exist"
}
"commands": [
"mv tmp/testfile tmp2"
]
}
19 changes: 19 additions & 0 deletions tests/operations/files.move/missing_dest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"kwargs": {
"src": "/tmp/src_dir/file",
"dest": "/tmp/dest_dir",
"overwrite": false
},
"facts": {
"files.File": {
"path=/tmp/src_dir/file": true,
"path=/tmp/dest_dir/file": null
},
"files.Directory": {
"path=/tmp/dest_dir": null
}
},
"commands": [
"mv /tmp/src_dir/file /tmp/dest_dir"
]
}
5 changes: 1 addition & 4 deletions tests/operations/files.unarchive/remote_archive_missing.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,5 @@
"path=/tmp/missing.tar.gz": null
}
},
"exception": {
"name": "OperationError",
"message": "Remote archive /tmp/missing.tar.gz does not exist"
}
"commands": ["tar -xz -f /tmp/missing.tar.gz -C /opt/app"]
}
Loading