Skip to content

Conversation

@Gijsreyn
Copy link
Contributor

PR Summary

This pull request adds the shallowMerge function, including its reference documentation. Also documented the tryWhich().

PR Context

Partially addresses #57.


The `shallowMerge()` function takes an array of objects and combines them into a single
object by merging their properties. When the same property name appears in multiple objects,
the value from the last object in the array takes precedence.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
the value from the last object in the array takes precedence.
the value from the last object in the array with that property takes precedence.

object by merging their properties. When the same property name appears in multiple objects,
the value from the last object in the array takes precedence.

This is a **shallow merge**, meaning:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is a **shallow merge**, meaning:
This is a _shallow merge_, which applies the following rules:

Comment on lines +26 to +29
- Top-level properties are merged from all objects
- If a property value is an object, it replaces the entire object from previous objects
rather than merging the nested properties
- Arrays and other complex types are also replaced entirely, not combined
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Top-level properties are merged from all objects
- If a property value is an object, it replaces the entire object from previous objects
rather than merging the nested properties
- Arrays and other complex types are also replaced entirely, not combined
- The first object in the array defines the base value for the merged object.
- The function processes each object in the array in the order they're defined.
- When processing each object, the function iterates over every top-level property defined for that
object and:
- If the merged object doesn't already have the property, the function adds that property to the
merged object with the value from the current object.
- If the merged object does have the property, the function _replaces_ the existing value with
the value from the current object, even when the value is an object or array.

Comment on lines +33 to +36
- Building composite configuration objects from multiple sources
- Applying configuration overrides where later values take precedence
- Combining default settings with user-specified customizations
- Merging environment-specific configurations
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Building composite configuration objects from multiple sources
- Applying configuration overrides where later values take precedence
- Combining default settings with user-specified customizations
- Merging environment-specific configurations
- Building composite configuration objects from multiple sources.
- Applying configuration overrides where later values take precedence.
- Combining default settings with user-specified customizations.
- Merging environment-specific configurations.

Comment on lines +38 to +40
The shallow merge behavior differs from a deep merge (like [`union()`][00]) where nested
objects would be recursively merged. With `shallowMerge()`, nested structures are replaced
entirely by the last object's value.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The shallow merge behavior differs from a deep merge (like [`union()`][00]) where nested
objects would be recursively merged. With `shallowMerge()`, nested structures are replaced
entirely by the last object's value.
The shallow merge behavior differs from a deep merge (like [`union()`][00]) where nested
objects are recursively merged. The `shallowMerge()` function replaces nested structures
entirely with the value defined by the last object with that property in the input array.

Comment on lines +109 to +110
This tries `python3` first, falls back to `python`, and finally uses a default path if
neither is found in PATH.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This tries `python3` first, falls back to `python`, and finally uses a default path if
neither is found in PATH.
In this example, the function first looks for `python3` in the `PATH` environmental variable. If
that executable isn't discovered, it then looks for `python`. If neither executable is discovered,
it falls back to the specified default value, `/usr/bin/python3`.

docker: "[tryWhich('docker')]"
kubectl: "[tryWhich('kubectl')]"
helm: "[tryWhich('helm')]"
allFound: "[and(not(equals(tryWhich('docker'), null())), not(equals(tryWhich('kubectl'), null())), not(equals(tryWhich('helm'), null())))]"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
allFound: "[and(not(equals(tryWhich('docker'), null())), not(equals(tryWhich('kubectl'), null())), not(equals(tryWhich('helm'), null())))]"
allFound: >-
[and(
not(equals(tryWhich('docker'), null())),
not(equals(tryWhich('kubectl'), null())),
not(equals(tryWhich('helm'), null()))
)]

Comment on lines +159 to +160
The name of the executable to locate. On Windows, the function automatically checks for
common executable extensions (.exe, .cmd, .bat, .ps1, etc.) if no extension is provided.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The name of the executable to locate. On Windows, the function automatically checks for
common executable extensions (.exe, .cmd, .bat, .ps1, etc.) if no extension is provided.
The name of the executable to locate. On Windows, it automatically checks for common executable
extensions, like `.exe, `.cmd`, and `.bat`, if no extension is provided.

Comment on lines +179 to +182
The function returns `null` instead of generating errors when the executable is not found.
It will return an error only if:

- **Not a string**: The input is not a string (e.g., number, array, object, null)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The function returns `null` instead of generating errors when the executable is not found.
It will return an error only if:
- **Not a string**: The input is not a string (e.g., number, array, object, null)
The function returns `null` instead of generating errors when the executable isn't found.
The function only returns an error when the input isn't a string.

Comment on lines +186 to +192
- The function searches the PATH environment variable in the same order as the operating system
- On Windows, common executable extensions are automatically checked (.exe, .cmd, .bat, .ps1, etc.)
- Returns `null` (not an error) when the executable is not found
- The returned path is always absolute
- Use with [`if()`][00] or [`coalesce()`][01] for conditional logic based on tool availability
- The search is case-insensitive on Windows and case-sensitive on Unix-like systems
- Symbolic links are resolved to their target paths
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- The function searches the PATH environment variable in the same order as the operating system
- On Windows, common executable extensions are automatically checked (.exe, .cmd, .bat, .ps1, etc.)
- Returns `null` (not an error) when the executable is not found
- The returned path is always absolute
- Use with [`if()`][00] or [`coalesce()`][01] for conditional logic based on tool availability
- The search is case-insensitive on Windows and case-sensitive on Unix-like systems
- Symbolic links are resolved to their target paths
- The function searches the `PATH` environment variable in the same order as the operating system.
- On Windows, the function automatically checks for the executable with common extensions, like
`.exe`, `.cmd`, and `.bat`, when the input string doesn't define an extension. For example, if
the input is `dsc`, the function would return `dsc.exe` if available in `PATH`.
- The function returns `null` when the executable isn't found instead of raising an error.
- The function always returns the absolute path to a discovered executable.
- Use with [`if()`][00] or [`coalesce()`][01] for conditional logic based on tool availability.
- The function searches for the executable case-insensitively on Windows and case-sensitively on
other platforms.
- The function resolves symbolic links to their target paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants