@@ -245,12 +245,27 @@ public function isRightSideListsAsTree() : bool
245245
246246
247247 /**
248- * Prefixes array keys and transforms keys for rclone compatibility.
249- * Converts boolean values to "true" or "false" strings. All values are cast to string.
250- * Example: ['my-flag' => true] with prefix 'RCLONE_' becomes ['RCLONE_MY_FLAG' => 'true']
248+ * Prefixes array keys for rclone environment variables and transforms them.
249+ * - Removes leading '--' from keys.
250+ * - Replaces hyphens '-' with underscores '_' in keys.
251+ * - Converts keys to uppercase.
252+ * - Ensures the final key starts with the provided $prefix, avoiding duplication like "RCLONE_RCLONE_".
253+ * - If a key already starts with "RCLONE_", and $prefix is more specific (e.g., "RCLONE_CONFIG_REMOTE_"),
254+ * it correctly forms a key like "RCLONE_CONFIG_REMOTE_KEYNAME".
255+ * - Converts boolean values to "true" or "false" strings. All other values are cast to string.
256+ *
257+ * Example:
258+ * prefix_flags(['my-flag' => true], 'RCLONE_')
259+ * // Result: ['RCLONE_MY_FLAG' => 'true']
260+ * prefix_flags(['RCLONE_VERBOSE' => true], 'RCLONE_')
261+ * // Result: ['RCLONE_VERBOSE' => 'true'] (no double "RCLONE_")
262+ * prefix_flags(['timeout' => 30], 'RCLONE_CONFIG_MYREMOTE_')
263+ * // Result: ['RCLONE_CONFIG_MYREMOTE_TIMEOUT' => '30']
264+ * prefix_flags(['RCLONE_TIMEOUT' => 30], 'RCLONE_CONFIG_MYREMOTE_')
265+ * // Result: ['RCLONE_CONFIG_MYREMOTE_TIMEOUT' => '30']
251266 *
252267 * @param array $arr The input array of flags or parameters.
253- * @param string $prefix The prefix to add to each key (default: 'RCLONE_').
268+ * @param string $prefix The prefix to apply (e.g., 'RCLONE_', 'RCLONE_CONFIG_MYREMOTE_ ').
254269 *
255270 * @return array The processed array with prefixed keys and string-cast values.
256271 */
@@ -263,19 +278,43 @@ public static function prefix_flags(array $arr, string $prefix = 'RCLONE_') : ar
263278 $ replace_patterns = ['/^--/m ' => '' , '/-/m ' => '_ ' ,];
264279
265280 foreach ($ arr as $ key => $ value ) {
266- // Apply transformations to the key
267- $ processed_key = preg_replace (array_keys ($ replace_patterns ), array_values ($ replace_patterns ), (string ) $ key );
268- $ processed_key = strtoupper ($ processed_key ); // Convert key to uppercase (e.g., 'max_depth' -> 'MAX_DEPTH')
281+ // Apply transformations to the key to get a "base" key name.
282+ // Example: '--log-level' becomes 'LOG_LEVEL', 'RCLONE_BUFFER_SIZE' remains 'RCLONE_BUFFER_SIZE'.
283+ $ base_key = preg_replace (array_keys ($ replace_patterns ), array_values ($ replace_patterns ), (string ) $ key );
284+ $ base_key = strtoupper ($ base_key );
269285
270- // Convert boolean values to their "true" or "false" string representations
286+ $ final_env_var_name ;
287+ // Check if the base_key already starts with the "RCLONE_" substring.
288+ if (str_starts_with ($ base_key , 'RCLONE_ ' )) {
289+ // Case 1: base_key is 'RCLONE_SOME_FLAG'.
290+ if ($ prefix === 'RCLONE_ ' ) {
291+ // If the target prefix is also just 'RCLONE_', the base_key is already correct.
292+ // Example: prefix_flags(['RCLONE_VERBOSE' => true], 'RCLONE_') -> 'RCLONE_VERBOSE'
293+ $ final_env_var_name = $ base_key ;
294+ } else {
295+ // If the target prefix is more specific (e.g., 'RCLONE_CONFIG_MYREMOTE_'),
296+ // we want to use the specific prefix and the part of the base_key *after* "RCLONE_".
297+ // Example: prefix_flags(['RCLONE_TIMEOUT' => 30], 'RCLONE_CONFIG_MYREMOTE_')
298+ // -> 'RCLONE_CONFIG_MYREMOTE_' + 'TIMEOUT'
299+ // -> 'RCLONE_CONFIG_MYREMOTE_TIMEOUT'
300+ $ final_env_var_name = $ prefix . substr ($ base_key , strlen ('RCLONE_ ' ));
301+ }
302+ } else {
303+ // Case 2: base_key is 'SOME_FLAG' (does not start with 'RCLONE_').
304+ // Simply prepend the target prefix.
305+ // Example: prefix_flags(['verbose' => true], 'RCLONE_') -> 'RCLONE_VERBOSE'
306+ // Example: prefix_flags(['type' => 's3'], 'RCLONE_CONFIG_MYREMOTE_') -> 'RCLONE_CONFIG_MYREMOTE_TYPE'
307+ $ final_env_var_name = $ prefix . $ base_key ;
308+ }
309+
310+ // Convert boolean values to their "true" or "false" string representations.
271311 if (is_bool ($ value )) {
272312 $ processed_value = $ value ? 'true ' : 'false ' ;
273313 } else {
274- // Ensure all other values are cast to string for environment variables
314+ // Ensure all other values are cast to string for environment variables.
275315 $ processed_value = (string ) $ value ;
276316 }
277- // Build the new key with the prefix and assign the processed value
278- $ newArr [$ prefix . $ processed_key ] = $ processed_value ;
317+ $ newArr [$ final_env_var_name ] = $ processed_value ;
279318 }
280319
281320 return $ newArr ;
@@ -285,7 +324,7 @@ public static function prefix_flags(array $arr, string $prefix = 'RCLONE_') : ar
285324 * Consolidates all environment variables for the rclone process.
286325 * This includes forced variables, provider-specific flags, global flags,
287326 * custom environment variables, and operation-specific flags.
288- * The order of merging determines precedence (later merges override earlier ones).
327+ * The order of `array_merge` determines precedence (later merges override earlier ones).
289328 * Precedence: Operation-Specific > Custom Envs > Global Flags > Provider Flags > Forced Vars.
290329 *
291330 * @param array $additional_operation_flags Flags specific to the current rclone operation (e.g., for copy, move).
0 commit comments