From ad93f286d7747a921b7c45349bbf3ff8cba6b163 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:22:59 +0000 Subject: [PATCH 1/5] Initial plan From 15ccdd290a50c88ba3fc280bd0e315b45a1ca1ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:28:07 +0000 Subject: [PATCH 2/5] Fix config-dir lookup to check user-specified directory first Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- tools/system/dmf-get/README.md | 15 ++++++-- tools/system/dmf-get/main.c | 66 ++++++++++++++++++++++------------ 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/tools/system/dmf-get/README.md b/tools/system/dmf-get/README.md index 2d2768f..86fe592 100644 --- a/tools/system/dmf-get/README.md +++ b/tools/system/dmf-get/README.md @@ -119,6 +119,15 @@ dmf-get dmclk@0.4 --config board/stm32f746g-disco.ini --config-dir ./config # 2. Look for board/stm32f746g-disco.ini in the module's config directory # 3. Copy it to ./config/dmclk/stm32f746g-disco.ini +# Use an external configuration file (from config-dir) +# If you have a config file in ./my-configs/board/stm32f746g-disco.ini +dmf-get dmclk --config board/stm32f746g-disco.ini --config-dir ./my-configs + +# This will: +# 1. Look for ./my-configs/board/stm32f746g-disco.ini first +# 2. If found, copy it to ./my-configs/dmclk/stm32f746g-disco.ini (same directory tree) +# 3. If not found, fall back to looking in the module's config directory + # Specify a custom destination filename (without module subdirectory) dmf-get mymodule --config mcu/default.ini --config-dir ./cfg --config-dest my.ini # Copies to: ./cfg/my.ini (instead of ./cfg/mymodule/default.ini) @@ -129,8 +138,10 @@ dmf-get mymodule --config boards/${BOARD}/config.ini --config-dir ./config -D BO ``` **Configuration File Lookup:** -1. The configuration file is searched in the module's config directory as specified in the `.dmr` file -2. If not found in `.dmr`, the default location `//config/` is used +1. If `` is an absolute path, it is used directly +2. If `` is relative, check `/` first (allows using external config files) +3. If not found in ``, search in the module's config directory as specified in the `.dmr` file +4. If not found in `.dmr`, try the default location `//config/` **Destination Naming:** - **Default behavior**: Configuration file is copied to `//` diff --git a/tools/system/dmf-get/main.c b/tools/system/dmf-get/main.c index 529649a..69c658f 100644 --- a/tools/system/dmf-get/main.c +++ b/tools/system/dmf-get/main.c @@ -1010,38 +1010,58 @@ static bool CopyConfigurationFile(const char* module_name, const char* config_pa DMOD_LOG_INFO("Looking for configuration file: %s for module: %s\n", substituted_config_path, module_name); - // First, check if the module has a .dmr file in the output directory - char dmr_path[DMOD_MAX_PATH_LEN]; - Dmod_SnPrintf(dmr_path, sizeof(dmr_path), "%s/%s.dmr", output_dir, module_name); - char config_source[DMOD_MAX_PATH_LEN] = ""; - // Try to find config directory path from .dmr file - if (Dmod_Access(dmr_path, DMOD_R_OK) == 0) { - Dmod_ResourceContext_t* res_ctx = Dmod_Resource_Init(output_dir, module_name); - if (res_ctx) { - if (Dmod_Resource_ParseFile(res_ctx, dmr_path)) { - size_t res_count = Dmod_Resource_GetEntryCount(res_ctx); - for (size_t i = 0; i < res_count; i++) { - Dmod_ResourceEntry_t res_entry; - if (Dmod_Resource_GetEntry(res_ctx, i, &res_entry)) { - // Look for "config" resource entry - if (strcmp(res_entry.key, "config") == 0 || - strcmp(res_entry.key, "configs") == 0) { - // Build full path: destination from .dmr + substituted config_path - Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s", - res_entry.destination, substituted_config_path); - DMOD_LOG_INFO("Found config directory in .dmr: %s\n", res_entry.destination); - break; + // First, check if config_path is an absolute path + if (substituted_config_path[0] == '/') { + strncpy(config_source, substituted_config_path, sizeof(config_source) - 1); + config_source[sizeof(config_source) - 1] = '\0'; + DMOD_LOG_INFO("Using absolute config path: %s\n", config_source); + } + // Second, check if config file exists in config_dest_dir (user-specified source directory) + else { + char user_config_path[DMOD_MAX_PATH_LEN]; + Dmod_SnPrintf(user_config_path, sizeof(user_config_path), "%s/%s", + config_dest_dir, substituted_config_path); + if (Dmod_Access(user_config_path, DMOD_R_OK) == 0) { + strncpy(config_source, user_config_path, sizeof(config_source) - 1); + config_source[sizeof(config_source) - 1] = '\0'; + DMOD_LOG_INFO("Found config in specified config-dir: %s\n", config_source); + } + } + + // Third, check if the module has a .dmr file in the output directory + if (config_source[0] == '\0') { + char dmr_path[DMOD_MAX_PATH_LEN]; + Dmod_SnPrintf(dmr_path, sizeof(dmr_path), "%s/%s.dmr", output_dir, module_name); + + // Try to find config directory path from .dmr file + if (Dmod_Access(dmr_path, DMOD_R_OK) == 0) { + Dmod_ResourceContext_t* res_ctx = Dmod_Resource_Init(output_dir, module_name); + if (res_ctx) { + if (Dmod_Resource_ParseFile(res_ctx, dmr_path)) { + size_t res_count = Dmod_Resource_GetEntryCount(res_ctx); + for (size_t i = 0; i < res_count; i++) { + Dmod_ResourceEntry_t res_entry; + if (Dmod_Resource_GetEntry(res_ctx, i, &res_entry)) { + // Look for "config" resource entry + if (strcmp(res_entry.key, "config") == 0 || + strcmp(res_entry.key, "configs") == 0) { + // Build full path: destination from .dmr + substituted config_path + Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s", + res_entry.destination, substituted_config_path); + DMOD_LOG_INFO("Found config directory in .dmr: %s\n", res_entry.destination); + break; + } } } } + Dmod_Resource_Free(res_ctx); } - Dmod_Resource_Free(res_ctx); } } - // If not found in .dmr, try default location: output_dir/module_name/config/ + // Finally, try default location: output_dir/module_name/config/ if (config_source[0] == '\0') { Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s/config/%s", output_dir, module_name, substituted_config_path); From 129d1c45bcf0879c3712975e0853145208ab4566 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:29:40 +0000 Subject: [PATCH 3/5] Use Dmod_SnPrintf for safer string handling in config lookup Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- tools/system/dmf-get/main.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/system/dmf-get/main.c b/tools/system/dmf-get/main.c index 69c658f..f7b45a9 100644 --- a/tools/system/dmf-get/main.c +++ b/tools/system/dmf-get/main.c @@ -1014,8 +1014,7 @@ static bool CopyConfigurationFile(const char* module_name, const char* config_pa // First, check if config_path is an absolute path if (substituted_config_path[0] == '/') { - strncpy(config_source, substituted_config_path, sizeof(config_source) - 1); - config_source[sizeof(config_source) - 1] = '\0'; + Dmod_SnPrintf(config_source, sizeof(config_source), "%s", substituted_config_path); DMOD_LOG_INFO("Using absolute config path: %s\n", config_source); } // Second, check if config file exists in config_dest_dir (user-specified source directory) @@ -1024,8 +1023,7 @@ static bool CopyConfigurationFile(const char* module_name, const char* config_pa Dmod_SnPrintf(user_config_path, sizeof(user_config_path), "%s/%s", config_dest_dir, substituted_config_path); if (Dmod_Access(user_config_path, DMOD_R_OK) == 0) { - strncpy(config_source, user_config_path, sizeof(config_source) - 1); - config_source[sizeof(config_source) - 1] = '\0'; + Dmod_SnPrintf(config_source, sizeof(config_source), "%s", user_config_path); DMOD_LOG_INFO("Found config in specified config-dir: %s\n", config_source); } } From b69dd611c8cbf889cfc1466a431f54cccb7a185f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:38:42 +0000 Subject: [PATCH 4/5] Revert incorrect changes - config files must come from module package only Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- tools/system/dmf-get/README.md | 15 ++------ tools/system/dmf-get/main.c | 64 ++++++++++++---------------------- 2 files changed, 25 insertions(+), 54 deletions(-) diff --git a/tools/system/dmf-get/README.md b/tools/system/dmf-get/README.md index 86fe592..2d2768f 100644 --- a/tools/system/dmf-get/README.md +++ b/tools/system/dmf-get/README.md @@ -119,15 +119,6 @@ dmf-get dmclk@0.4 --config board/stm32f746g-disco.ini --config-dir ./config # 2. Look for board/stm32f746g-disco.ini in the module's config directory # 3. Copy it to ./config/dmclk/stm32f746g-disco.ini -# Use an external configuration file (from config-dir) -# If you have a config file in ./my-configs/board/stm32f746g-disco.ini -dmf-get dmclk --config board/stm32f746g-disco.ini --config-dir ./my-configs - -# This will: -# 1. Look for ./my-configs/board/stm32f746g-disco.ini first -# 2. If found, copy it to ./my-configs/dmclk/stm32f746g-disco.ini (same directory tree) -# 3. If not found, fall back to looking in the module's config directory - # Specify a custom destination filename (without module subdirectory) dmf-get mymodule --config mcu/default.ini --config-dir ./cfg --config-dest my.ini # Copies to: ./cfg/my.ini (instead of ./cfg/mymodule/default.ini) @@ -138,10 +129,8 @@ dmf-get mymodule --config boards/${BOARD}/config.ini --config-dir ./config -D BO ``` **Configuration File Lookup:** -1. If `` is an absolute path, it is used directly -2. If `` is relative, check `/` first (allows using external config files) -3. If not found in ``, search in the module's config directory as specified in the `.dmr` file -4. If not found in `.dmr`, try the default location `//config/` +1. The configuration file is searched in the module's config directory as specified in the `.dmr` file +2. If not found in `.dmr`, the default location `//config/` is used **Destination Naming:** - **Default behavior**: Configuration file is copied to `//` diff --git a/tools/system/dmf-get/main.c b/tools/system/dmf-get/main.c index f7b45a9..529649a 100644 --- a/tools/system/dmf-get/main.c +++ b/tools/system/dmf-get/main.c @@ -1010,56 +1010,38 @@ static bool CopyConfigurationFile(const char* module_name, const char* config_pa DMOD_LOG_INFO("Looking for configuration file: %s for module: %s\n", substituted_config_path, module_name); - char config_source[DMOD_MAX_PATH_LEN] = ""; + // First, check if the module has a .dmr file in the output directory + char dmr_path[DMOD_MAX_PATH_LEN]; + Dmod_SnPrintf(dmr_path, sizeof(dmr_path), "%s/%s.dmr", output_dir, module_name); - // First, check if config_path is an absolute path - if (substituted_config_path[0] == '/') { - Dmod_SnPrintf(config_source, sizeof(config_source), "%s", substituted_config_path); - DMOD_LOG_INFO("Using absolute config path: %s\n", config_source); - } - // Second, check if config file exists in config_dest_dir (user-specified source directory) - else { - char user_config_path[DMOD_MAX_PATH_LEN]; - Dmod_SnPrintf(user_config_path, sizeof(user_config_path), "%s/%s", - config_dest_dir, substituted_config_path); - if (Dmod_Access(user_config_path, DMOD_R_OK) == 0) { - Dmod_SnPrintf(config_source, sizeof(config_source), "%s", user_config_path); - DMOD_LOG_INFO("Found config in specified config-dir: %s\n", config_source); - } - } + char config_source[DMOD_MAX_PATH_LEN] = ""; - // Third, check if the module has a .dmr file in the output directory - if (config_source[0] == '\0') { - char dmr_path[DMOD_MAX_PATH_LEN]; - Dmod_SnPrintf(dmr_path, sizeof(dmr_path), "%s/%s.dmr", output_dir, module_name); - - // Try to find config directory path from .dmr file - if (Dmod_Access(dmr_path, DMOD_R_OK) == 0) { - Dmod_ResourceContext_t* res_ctx = Dmod_Resource_Init(output_dir, module_name); - if (res_ctx) { - if (Dmod_Resource_ParseFile(res_ctx, dmr_path)) { - size_t res_count = Dmod_Resource_GetEntryCount(res_ctx); - for (size_t i = 0; i < res_count; i++) { - Dmod_ResourceEntry_t res_entry; - if (Dmod_Resource_GetEntry(res_ctx, i, &res_entry)) { - // Look for "config" resource entry - if (strcmp(res_entry.key, "config") == 0 || - strcmp(res_entry.key, "configs") == 0) { - // Build full path: destination from .dmr + substituted config_path - Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s", - res_entry.destination, substituted_config_path); - DMOD_LOG_INFO("Found config directory in .dmr: %s\n", res_entry.destination); - break; - } + // Try to find config directory path from .dmr file + if (Dmod_Access(dmr_path, DMOD_R_OK) == 0) { + Dmod_ResourceContext_t* res_ctx = Dmod_Resource_Init(output_dir, module_name); + if (res_ctx) { + if (Dmod_Resource_ParseFile(res_ctx, dmr_path)) { + size_t res_count = Dmod_Resource_GetEntryCount(res_ctx); + for (size_t i = 0; i < res_count; i++) { + Dmod_ResourceEntry_t res_entry; + if (Dmod_Resource_GetEntry(res_ctx, i, &res_entry)) { + // Look for "config" resource entry + if (strcmp(res_entry.key, "config") == 0 || + strcmp(res_entry.key, "configs") == 0) { + // Build full path: destination from .dmr + substituted config_path + Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s", + res_entry.destination, substituted_config_path); + DMOD_LOG_INFO("Found config directory in .dmr: %s\n", res_entry.destination); + break; } } } - Dmod_Resource_Free(res_ctx); } + Dmod_Resource_Free(res_ctx); } } - // Finally, try default location: output_dir/module_name/config/ + // If not found in .dmr, try default location: output_dir/module_name/config/ if (config_source[0] == '\0') { Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s/config/%s", output_dir, module_name, substituted_config_path); From bd664035414bef942ede0f0cfdf020b4e5a7206f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 8 Feb 2026 12:50:16 +0000 Subject: [PATCH 5/5] Fix config file installation for modules without .dmr files When a module doesn't have a .dmr resource file, the entire package contents are now copied to output_dir/module_name/ directory. This ensures config files and other resources are accessible. Also fixed config directory name lookup to try both "configs" (plural) and "config" (singular) as different modules may use either convention. Fixes the issue where dmclk module's config files couldn't be found. Co-authored-by: JohnAmadis <17320783+JohnAmadis@users.noreply.github.com> --- tools/system/dmf-get/main.c | 47 ++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/tools/system/dmf-get/main.c b/tools/system/dmf-get/main.c index 529649a..8e816ca 100644 --- a/tools/system/dmf-get/main.c +++ b/tools/system/dmf-get/main.c @@ -1041,11 +1041,22 @@ static bool CopyConfigurationFile(const char* module_name, const char* config_pa } } - // If not found in .dmr, try default location: output_dir/module_name/config/ + // If not found in .dmr, try default locations: output_dir/module_name/configs/ and output_dir/module_name/config/ if (config_source[0] == '\0') { - Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s/config/%s", + // Try "configs" first (plural - common convention) + char config_path_plural[DMOD_MAX_PATH_LEN]; + Dmod_SnPrintf(config_path_plural, sizeof(config_path_plural), "%s/%s/configs/%s", output_dir, module_name, substituted_config_path); - DMOD_LOG_INFO("Using default config location: %s\n", config_source); + + if (Dmod_Access(config_path_plural, DMOD_R_OK) == 0) { + Dmod_SnPrintf(config_source, sizeof(config_source), "%s", config_path_plural); + DMOD_LOG_INFO("Using default config location: %s\n", config_source); + } else { + // Fall back to "config" (singular) + Dmod_SnPrintf(config_source, sizeof(config_source), "%s/%s/config/%s", + output_dir, module_name, substituted_config_path); + DMOD_LOG_INFO("Using default config location: %s\n", config_source); + } } // Validate paths for safety - prevents command injection through shell metacharacters @@ -1612,6 +1623,36 @@ static bool ExtractZipAndFindModule(const char* zip_path, const char* output_dir Dmod_Resource_Free(res_ctx); } } + } else { + // No .dmr file found - copy entire extracted directory to output_dir/module_name/ + // This ensures config files and other resources are available + DMOD_LOG_INFO("No .dmr file found, copying entire package structure\n"); + + char module_dir[1024]; + Dmod_SnPrintf(module_dir, sizeof(module_dir), "%s/%s", output_dir, module_name); + + // Validate path for safety + if (IsPathSafe(module_dir)) { + // Create module directory + char mkdir_cmd[2048]; + Dmod_SnPrintf(mkdir_cmd, sizeof(mkdir_cmd), "mkdir -p \"%s\"", module_dir); + int mkdir_result = system(mkdir_cmd); + + if (mkdir_result == 0) { + // Copy all contents from extract_dir to module_dir + char cp_all_cmd[2048]; + Dmod_SnPrintf(cp_all_cmd, sizeof(cp_all_cmd), "cp -r \"%s/.\" \"%s/\"", extract_dir, module_dir); + int cp_result = system(cp_all_cmd); + + if (cp_result == 0) { + DMOD_LOG_INFO("Package contents copied to: %s\n", module_dir); + } else { + DMOD_LOG_WARN("Failed to copy package contents to module directory\n"); + } + } else { + DMOD_LOG_WARN("Failed to create module directory: %s\n", module_dir); + } + } } // Clean up: remove ZIP file and temp directory