File
kind: file
source | condition | target |
---|---|---|
✔ | ✔ | ✔ |
Description
source
The File "source" retrieves the content of a file (from the local filesystem or from a remote URL).
condition
The File "condition" tests if the content of a file (either local or remote URL) matches the specified constraints.
target
The File "target" updates a the content of a file (only local filesystem) from the input source value and specified constraints.
Parameters
The following parameters can be specified through the spec
attributes map:
Name | Type | Description | Required |
---|---|---|---|
content | string |
| |
file | string |
| |
files | array |
| |
forcecreate | boolean |
| |
line | integer |
| |
matchpattern | string |
| |
replacepattern | string |
| |
searchpattern | boolean |
|
Links :
File Location
The location of the file (attribute file
) can be specified as an URL (prefixed with https://
or http://
) or as a local filesystem path (optional prefix file://
or any relative or absolute path of the current operating system: Unix or Windows)
File Source
It retrieves the content of the file at the location file
and use it as the source value.
💡 Please note that the source value might be a multiline string with endline characters.
⚠️ A file source does not support the following attributes (and is expected to error):
content
forcecreate
replacepattern
Filtering File Source Content
You may filter the content with one of the options below:
If the attribute
spec.line
is specified, then the source value is set to the content of this line onlyIf the attribute
spec.matchpattern
is specified, then the source value is set to the matched content in the fileThe specified pattern must be a valid Golang regexp
When there are no matched content (e.g. the matched content is the empty string), then the source fails
Source Examples
The following example should result in a source value set to the whole content of the file
./README.md
:updateCli.yaml:sources: ContentFromLocalFile: kind: file spec: file: README.md
README.md:# Read Me Hello world
$ updatecli apply # ... SOURCES ======= ContentFromLocalFile -------------------- ✔ Content: found from file "README.md": # Read Me Hello world ============================= # ...
The following example should result in a source value set to the whole content of the file located at the URL
https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
:updateCli.yaml:sources: ContentFromURL: kind: file spec: file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
$ updatecli apply # ... SOURCES ======= ContentFromURL -------------- ✔ Content: found from file "https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS": 363d0e0c5c4cb4e69f5f2c7f64f9bf01ab73af0801665d577441521a24313a07 terraform_0.14.5_darwin_amd64.zip 5a3e0c7873faa048f59d563a2a98caf7f04045967cbb5ad6cf05f5991e20b8d1 terraform_0.14.5_freebsd_386.zip 4b7f2b878a9854652493b2c94ac586586f2ab53f93e3baa55fc2199ccd5a042d terraform_0.14.5_freebsd_amd64.zip 03c201a9a3e1d2776d0cfc0163e52484f3dbbbd73eb08d5bac491ca87a9aa3b7 terraform_0.14.5_freebsd_arm.zip b262998c85a7cad1c24b90f3d309d592bd349d411167a2939eb482dc2b99702d terraform_0.14.5_linux_386.zip 2899f47860b7752e31872e4d57b1c03c99de154f12f0fc84965e231bc50f312f terraform_0.14.5_linux_amd64.zip a971a5f5da82ea896a2e91fd828c90ea9c28e3de575d03a7ce25a5840ed7ae2b terraform_0.14.5_linux_arm.zip d3cab7d777eec230b67eb9723f3b271cd43e29c688439e4c67e3398cdaf6406b terraform_0.14.5_linux_arm64.zip 67b153c8c754ca03e3f8954b201cf27ec31387c8d3c77d302d647417bc4a23f4 terraform_0.14.5_openbsd_386.zip 062fbc3f596490e33e6493a8e186ae50e7b6077ac2a842392991d918189187fc terraform_0.14.5_openbsd_amd64.zip f66920ffedd7e81cd116d185ada479ba466f5514f8b20194cc180d3c6184e060 terraform_0.14.5_solaris_amd64.zip f8bf1fca0ef11a33955d225198d1211e15827d43488cc9174dcda14d1a7a1d19 terraform_0.14.5_windows_386.zip 5d25f9afc71fc49d5f3e8c7ccc3ccd83a840c56e7a015f55f321fc970a73050b terraform_0.14.5_windows_amd64.zip ============================= # ...
The following example should result in a source value set to
Hello World
(e.g. the 2nd line of the file./README.md
):source-file.yaml:sources: ContentFromLocalFile: kind: file spec: file: README.md line: 2
README.md:# Read Me Hello world
$ updatecli apply # ... SOURCES ======= ContentFromLocalFile -------------------- ✔ Content: found from file "README.md": Hello world ============================= # ...
The following example should result in a source value set to
2899f47860b7752e31872e4d57b1c03c99de154f12f0fc84965e231bc50f312f terraform_0.14.5_linux_amd64.zip
(e.g. the only line matching the pattern'.terraform_.*_linux_amd64.'
at the URLhttps://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
):updateCli.yaml:sources: ContentFromURL: kind: file spec: file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS matchpattern: '.*terraform_.*_linux_amd64.*'
$ updatecli apply # ... SOURCES ======= ContentFromURL -------------- ✔ Content: found from file "https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS": 2899f47860b7752e31872e4d57b1c03c99de154f12f0fc84965e231bc50f312f terraform_0.14.5_linux_amd64.zip ============================= # ...
File Condition
It checks that the content of the file matches the specified content and continue the pipeline execution, or fails the pipeline (and never run the pipeline’s targets).
⚠️ A file condition does not support the following attributes (and is expected to error):
forcecreate
replacepattern
Condition Input Value
The "Input Value" is the string to compare with the specified file content.
By default, the input value is set to the input source value associated to the condition
(e.g. either the source specified with the sourceid
attribute or the only source if the pipeline only have one).
Alternatively you can disable the source input value with disablesourceinput: true
and specify a custom content with the spec.content
attribute (see examples below).
⚠️ If both a source input value and a spec.content
are detected, then the condition fails with an error.
Filtering File Condition Content
You may filter the content of the file to be compared to the [Input Value] with one of the options below:
If the attribute
spec.line
is specified, then the input value is only compared to the content of this lineIf the attribute
spec.matchpattern
is specified, then the input value is only compared to the matched content in the fileThe specified pattern must be a valid Golang regexp
Condition Examples
The following example returns "true" if the content of the file
./LICENSE
is the same as the value of the source namedContentFromURL
:conditions: LocalFileHasSameContentAsSource: kind: file sourceid: ContentFromURL spec: file: LICENSE
$ updatecli apply # ... CONDITIONS: =========== LocalFileHasSameContentAsSource ------------------------------- ✔ Content of the file "LICENSE" is the same as the input source value. =============================
The following example returns "true" if the content of the URL
https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
is the same as the value of the source namedchecksums
:updateCli.yaml# ... conditions: URLHasSameContentAsSource: kind: file sourceid: checksums spec: file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
$ updatecli apply # ... CONDITIONS: =========== URLHasSameContentAsSource ------------------------------- ✔ Content of the file "https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS" is the same as the input source value. =============================
The following example returns "true" if the line n°2 of the local file
README.md
is equal to the specified contentHello world
(input value defers tospec.content
as the input source is disabled):updateCli.yamlconditions: LocalFileHasLineMatchingCustomContent: kind: file disablesourceinput: true spec: file: README.md line: 2 content: 'Hello world'
$ updatecli apply # ... CONDITIONS: =========== LocalFileHasLineMatchingCustomContent ------------------------------------- ✔ Content of the file "README.md" (line 2) is the same as the specified content. =============================
The following example returns "true" if the line n°5 of the local file
README.md
exists (e.g. is not empty, because no source input value and nospec.content
are specified):updateCli.yamlconditions: LocalFileHasLine2NonEmpty: kind: file disablesourceinput: true spec: file: README.md line: 2
$ updatecli apply # ... CONDITIONS: =========== LocalFileHasLine2NonEmpty ------------------------- ✔ Content of the file "README.md" (line 2) is not empty and the file exists. =============================
The following example returns "true" if the content from the URL
https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
matches the pattern'.terraform_.*_linux.'
(there are 4 lines matching this pattern in this example):updateCli.yamlconditions: UrlContentMatchesPattern: kind: file disablesourceinput: true spec: file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS matchpattern: '.*terraform_.*_linux.*'
$ updatecli apply # ... CONDITIONS: =========== UrlContentMatchesPattern ------------------------ ✔ Content of the file "https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS" matched the pattern ".*terraform_.*_linux.*" =============================
File Target
It writes the input value into the specified file. The content update can be restricted (see the section Restricting File Content Update below) and the file can be created if it does not exist.
⚠️ A file target only supports local files but does not support URLs (remote files).
Create File When Absent
By default, a file target errors when the specified file does not exist.
If you want to force the creation of the file prior to the file target execution,
you can specify the spec.forcecreate
attribute to true
.
⚠️ If the attribute spec.line
is defined along with spec.forcecreate
, then the target is expected to fail, as it makes no sense to write a line in a file which does not exist.
Target Input Value
The "Input Value" is the string to write to the specified file.
By default, the input value is set to the input source value associated to the target (e.g. either the source specified with the
sourceid
attribute or the only source if the pipeline only have one).You can also specify a custom content with the
spec.content
attribute instead of using the input source value. Using thespec.content
is useful when you need to templatize with the source input value (see example below).Finally, you can define a Golang regexp in the attribute
spec.ReplacePattern
, if and only if you also specified aspec.matchpattern
(see Restricting File Content Update and Target Examples for more details).Regexp’s capturing group are supported (this is the recommended use case)
Restricting File Content Update
You may restrict which part of the specified file to be updated with the input value with the following options:
If the attribute
spec.line
is specified, then the input value is only written to the specified line.When the input value is a multi-line string, then additional lines are inserted (the 1st line of the input value is written to the specified line, and subsequent input value’s lines are inserted)
If the attribute
spec.matchpattern
is specified, then all the matching patterns are replaced by the input value.The specified pattern must be a valid Golang regexp
As described in Target Input Value, the input value can be the input source, a content string or a regexp "replace pattern"
Please note that the matched content can be a line but also a substring!
Target Examples
The following target writes the result of the input source
generatedReadMeContent
to the fileREADME.md
(overriding the existing content) and creates the file if does not exist:updateCli.yaml:# .. targets: setFileContent: kind: file sourceid: generatedReadMeContent spec: file: README.md forcecreate: true
$ updatecli diff #... TARGETS ======== setFileContent -------------- **Dry Run enabled** Creating a new file at "README.md" ✔ File content for "README.md", updated. < --- > # ReadMe > Hello world
The following target only overrides the 3rd line of the file
versions.txt
with the templatized value specified with thespec.content
attribute. In this example, is defines a new version from the input source namedgetMavenVersion
:updateCli.yaml:# .. targets: updateCopyrightYear: kind: file sourceid: getMavenVersion # Source Value is "3.8.3" spec: file: versions.txt line: 3 content: maven_version = "{{ source `getMavenVersion` }}"
$ updatecli diff #... TARGETS ======== setLineOfFileWithContent ------------------------ **Dry Run enabled** ✔ The line 3 of the file "versions.txt" was updated: < maven_version = "3.6.2" --- > maven_version = "3.8.3"
The following target replaces, in the file
LICENSE
, the string occurrences matched by the patternCopyright \(c\) (\d*) (.*)
by the stringCopyright (c) 2021 $2
where$2
is the content right-matched by(.*)
(e.g this example updates the year on the "Copyright" substrings to 2021 while keeping the existing content such as contributors).:updateCli.yaml:# .. targets: updateCopyrightYear: kind: file sourceid: whateverSource # Will be ignored as `replacepattern` is specified spec: file: LICENSE matchpattern: 'Copyright \(c\) (\d*) (.*)' replacepattern: 'Copyright (c) 2021 $2'
$ updatecli diff TARGETS ======== updateCopyrightYear -------------- **Dry Run enabled** ✔ File content for "LICENSE", updated. < Copyright (c) 2020 Olblak --- > Copyright (c) 2021 Olblak
Reference
---
title: Show a set of file resources as a generic example
sources:
ContentFromLocalFile:
kind: file
spec:
file: LICENSE
ContentFromURL:
kind: file
spec:
file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
LineFromLocalFile:
kind: file
spec:
file: LICENSE
line: 3
LineFromURL:
kind: file
spec:
file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
line: 3
SingleLineFromFileWithPattern:
kind: file
spec:
file: LICENSE
matchpattern: 'Copyright.*' # Returns a single line
MultipleLinesFromURLWithPattern:
kind: file
spec:
file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
matchpattern: '.*terraform_.*_linux.*' # Returns a multi-line content as multiple lines are matched
conditions:
LocalFileHasSameContentAsSource:
kind: file
sourceid: ContentFromLocalFile
spec:
file: LICENSE
URLFileMatchesSpecifiedContent:
kind: file
disablesourceinput: true
spec:
file: https://get.helm.sh/helm-v3.5.0-darwin-amd64.tar.gz.sha256sum
content: |
53378d8de087395ece3876795111a8077f2451f080ec6150d777cc3105214520 helm-v3.5.0-darwin-amd64.tar.gz
LocalFileHasLine:
kind: file
disablesourceinput: true
spec:
file: LICENSE
line: 5 # The file './LICENSE' has a 5th line which is NOT empty
URLFileHasLineMatchingSource:
kind: file
sourceid: LineFromURL
spec:
file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
line: 3 # The line 3 of the file matches the source LineFromURL
LocalFileHasLineMatchingSource:
kind: file
sourceid: LineFromLocalFile
spec:
file: LICENSE
line: 3 # The file './LICENSE' has a 3rd line which is NOT empty and matches the source LineFromLocalFile
LocalFileHasLineMatchingCustomContent:
kind: file
disablesourceinput: true
spec:
file: LICENSE
line: 3
content: '{{ source `LineFromLocalFile` }}'
LocalFileMatchesPattern:
kind: file
disablesourceinput: true
spec:
file: "LICENSE"
matchpattern: 'Copyright \(c\) (\d*) Olblak'
######## Expected Failures
## Should fail condition if uncommented
# LocalFileHasDifferentContentAsSource:
# kind: file
# sourceid: ContentFromURL
# spec:
# file: LICENSE
# URLFileDifferentThanSpecifiedContent:
# kind: file
# disablesourceinput: true
# spec:
# file: https://releases.hashicorp.com/terraform/0.14.5/terraform_0.14.5_SHA256SUMS
# content: |
# 53378d8de087395ece3876795111a8077f2451f080ec6150d777cc3105214520 helm-v3.5.0-darwin-amd64.tar.gz
# LocalFileDoesNotHasLine:
# kind: file
# disablesourceinput: true
# spec:
# file: LICENSE
# line: 12345 # The file './LICENSE' does NOT have a 12345th line
## Should fail validation if uncommented
# FailsToValidateBecauseMutuallyExclusiveAttributes:
# kind: file
# sourceid: ContentFromLocalFile
# spec:
# file: https://get.helm.sh/helm-v3.5.0-darwin-amd64.tar.gz.sha256sum
# content: |
# 53378d8de087395ece3876795111a8077f2451f080ec6150d777cc3105214520 helm-v3.5.0-darwin-amd64.tar.gz
targets:
setFileContent:
kind: file
sourceid: ContentFromURL
spec:
file: terraform_0.14.5_SHA256SUMS
forcecreate: true
setLineOfFile:
kind: file
sourceid: LineFromLocalFile
spec:
file: LICENSE
line: 5
setLineOfFileWithContent:
kind: file
sourceid: LineFromLocalFile
spec:
file: LICENSE
line: 3
content: oldline was "{{ source `LineFromLocalFile` }}"
setLineWithMatchAndReplacePatterns:
kind: file
sourceid: ContentFromURL
spec:
file: LICENSE
matchpattern: 'Copyright \(c\) (\d*) (.*)'
replacepattern: 'Copyright (c) 2021 $2'
setLineWithMatchAndContent:
kind: file
sourceid: ContentFromURL
spec:
file: LICENSE
matchpattern: 'Copyright \(c\) (\d*) (.*)'
content: 'Copyright (c) 2021 FooBar'
setLineWithMatchAndSource:
kind: file
sourceid: ContentFromURL
spec:
file: LICENSE
matchpattern: 'Copyright \(c\) (\d*) (.*)'