From ca20a1dc558ce16b63353cc5bf9abd39713148fa Mon Sep 17 00:00:00 2001 From: Anders Wiggers <47324009+anders-wiggers@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:27:23 +0200 Subject: [PATCH 1/2] Refactor extra_files handling in bundle.py refactoring of extra_files to handle building bundle for deployment which done in a sub-directory. --- rsconnect/bundle.py | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/rsconnect/bundle.py b/rsconnect/bundle.py index fe02ae51..88a7314d 100644 --- a/rsconnect/bundle.py +++ b/rsconnect/bundle.py @@ -1396,17 +1396,19 @@ def make_quarto_manifest( """ if environment: extra_files = list(extra_files or []) - + else: + extra_files = list(extra_files or []) + base_dir = file_or_directory if isdir(file_or_directory): # Directory as a Quarto project. excludes = list(excludes or []) + [".quarto"] - + project_config = quarto_inspection.get("config", {}).get("project", {}) output_dir = cast(Union[str, None], project_config.get("output-dir", None)) if output_dir: excludes = excludes + [output_dir] - + files_data = quarto_inspection.get("files", {}) files_input_data = files_data.get("input", []) # files.input is a list of absolute paths to input (rendered) @@ -1419,19 +1421,26 @@ def make_quarto_manifest( for each in files_input_data: t, _ = splitext(os.path.relpath(each, file_or_directory)) excludes = excludes + [t + ".html", t + "_files/**/*"] - + # relevant files don't need to include requirements.txt file because it is # always added to the manifest (as a buffer) from the environment contents if environment: excludes.append(environment.filename) - + relevant_files = _create_quarto_file_list(base_dir, extra_files, excludes) else: # Standalone Quarto document - base_dir = dirname(file_or_directory) - file_name = basename(file_or_directory) - relevant_files = [file_name] + list(extra_files or []) - + + # Use the common directory of the qmd and any extra files as base_dir. + # This avoids having the subfolder appear in both base_dir and rel_path. + all_files = [file_or_directory] + extra_files + + abs_paths = [os.path.abspath(p) for p in all_files] + base_dir = os.path.commonpath(abs_paths) + + # Store paths relative to base_dir + relevant_files = [os.path.relpath(p, base_dir) for p in abs_paths] + manifest = make_source_manifest( app_mode, environment, @@ -1441,13 +1450,13 @@ def make_quarto_manifest( env_management_py, env_management_r, ) - + if environment: manifest_add_buffer(manifest, environment.filename, environment.contents) - + for rel_path in relevant_files: manifest_add_file(manifest, rel_path, base_dir) - + return manifest, relevant_files From 1a5abd202a3f54057cc97b7e070a495cd7a4f463 Mon Sep 17 00:00:00 2001 From: Anders Wiggers <47324009+anders-wiggers@users.noreply.github.com> Date: Mon, 30 Mar 2026 14:34:56 +0200 Subject: [PATCH 2/2] minor cleanup --- rsconnect/bundle.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/rsconnect/bundle.py b/rsconnect/bundle.py index 88a7314d..5304000b 100644 --- a/rsconnect/bundle.py +++ b/rsconnect/bundle.py @@ -1396,19 +1396,15 @@ def make_quarto_manifest( """ if environment: extra_files = list(extra_files or []) - else: - extra_files = list(extra_files or []) base_dir = file_or_directory if isdir(file_or_directory): # Directory as a Quarto project. excludes = list(excludes or []) + [".quarto"] - project_config = quarto_inspection.get("config", {}).get("project", {}) output_dir = cast(Union[str, None], project_config.get("output-dir", None)) if output_dir: excludes = excludes + [output_dir] - files_data = quarto_inspection.get("files", {}) files_input_data = files_data.get("input", []) # files.input is a list of absolute paths to input (rendered) @@ -1421,16 +1417,13 @@ def make_quarto_manifest( for each in files_input_data: t, _ = splitext(os.path.relpath(each, file_or_directory)) excludes = excludes + [t + ".html", t + "_files/**/*"] - # relevant files don't need to include requirements.txt file because it is # always added to the manifest (as a buffer) from the environment contents if environment: excludes.append(environment.filename) - relevant_files = _create_quarto_file_list(base_dir, extra_files, excludes) else: # Standalone Quarto document - # Use the common directory of the qmd and any extra files as base_dir. # This avoids having the subfolder appear in both base_dir and rel_path. all_files = [file_or_directory] + extra_files @@ -1450,13 +1443,10 @@ def make_quarto_manifest( env_management_py, env_management_r, ) - if environment: - manifest_add_buffer(manifest, environment.filename, environment.contents) - + manifest_add_buffer(manifest, environment.filename, environment.contents) for rel_path in relevant_files: - manifest_add_file(manifest, rel_path, base_dir) - + manifest_add_file(manifest, rel_path, base_dir) return manifest, relevant_files