Google Workflows: How to get part of a string? - google-workflows

In the following workflow I want to return part of a string, for example:
- define:
assign:
- value: foobar
- returnValue:
return: ${value}
This would return foobar how would I return just foo?

This feature is now supported under the text library.
You can get part of the string using ${text.substring(value), 0, 3}

Related

How to show all the parameters names as comma separated string and assign to One Varaible in YAML Azure Pipelines

How to show all the parameter's names as comma-separated strings (concatenated) and assign them to One Variable in YAML Azure so that i can use this variable in several places
i tried using
parameters:
- name: Var1
displayName: Testing
type: string
- name: Var2
displayName: Coding
type: string
- name: Var3
displayName: Marketing
type: string
variables:
- name: allParametersString
${{each item in parameters}}:
value: $allParametersString + ','+ item.displayName
my desired output is upon using $allParametersString I should get
Testing,Coding,Marketing
but this is leaving an error mentioning 'value' is already defined so can anyone help me? regarding this, I am searching for a solution for 2 weeks :(
I found the way of using bash to assign values will work for this i did
variables:
- name: allParametersString
value: ' '
steps:
- ${{ each parameter in parameters }}:
# the below code will help us reassign the values to variables with bash so i am appending all parameters separated by comma
- bash: echo '##vso[task.setvariable variable=allParametersString]$(allParametersString)${{ parameter.Key }}, '
- script:
echo 'printing all parameters names separated by comma .->$(allParametersString)'
Please let me know if I can improve it more
this helps me understand that in order to reassign or assign twice or concatenate the string using YAML this is the one way of doing it
Your current thinking is not feasible.
There are several things that bind you.
1, The first is the processing logic of yml expression in DevOps.
See this official document:
https://learn.microsoft.com/en-us/azure/devops/pipelines/process/runs?view=azure-devops#process-the-pipeline
From the first sentence given, we know your yml will be expanded like this:
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
variables:
- name: allParametersString
value: xxx
value: xxx
value: xxx
variable of yml concept doesn't allow the written method of the above. That's why you encountered error 'value' is already defined.
2, The second is the structure allowed by DevOps yml files.
Every section of yml definition has limited predefined key. This means that compile time cannot find other container to store the variable.
3, I am afraid the usage of yml expression does not support you to do so.
Refer to this:
Each Keyword This tell you the standard usage of 'each':
You can use the each keyword to loop through parameters with the
object type.
JOIN Expression
This is the way the DevOps yml pipeline provides compile-time flattening of data, but it doesn't work in your case.
And there's no such thing as an index or subscript to navigate to the last run.
4, By the way, the item object doesn't have such information 'displayName':
trigger:
- none
parameters:
- name: Var1
displayName: Testing
type: string
default: value1
- name: Var2
displayName: Coding
type: string
default: value2
- name: Var3
displayName: Marketing
type: string
default: value3
steps:
- ${{each item in parameters}}:
- task: PowerShell#2
inputs:
targetType: 'inline'
script: |
# Write your PowerShell commands here.
Write-Host "${{ convertToJson(item) }}"
Result:
The DevOps yml pipeline has no built-in features to implement your needs. If you have to do this, a feasible method is to call the API to get the content of the yml file, then parse and get the parameter part (this is actually a self-designed parser), and then combine the acquired parameters into the variable in the script And pass logging command set variable(isoutput=true). In this way, other tasks can use this combined variable.
This can be done, but is overly complicated and you need to consider whether it is necessary to do such a thing.

Parse yaml with keys provide errors

I’ve the following yaml which I need to parse,
I’ve tried with the following
Build-t:
before: test1
- value : dddd
- bbb: zzzz
after: test2
- value: bbb
- aaa: aaaa
I’ve tried with the following:
type root struct{
build type Build `yaml:"Build-t,omitempty"`
}
type Build struct {
Before map[string]interface{} `yaml:"before,omitempty"`
After map[string]interface{} `yaml:"after,omitempty"`
}
Now when I parse it I got error,
What I need is to get the values from the object before and after which are hardcoded value in the yaml
And all the others value under it are dynmically can be added therefor I put it as interface
btw, if I change the root to this its working and I see all the fields under the Build-t but the before and after are like keys ...
type root struct{
build type map[string]interface{} `yaml:"Build-t,omitempty"`
}
the error is:
line 6: cannot unmarshal !!str `test1` into map[string]interface {}
line 7: cannot unmarshal !!str `test2` into map[string]interface {}
see the yaml valid here
https://codebeautify.org/yaml-validator/cb705458
That sounds correct - the YAML is invalid. Did you mean something like this?
Build-t:
before:
test1:
- value: dddd
- bbb: zzzz
after:
test2:
- value: bbb
- aaa: aaaa
Remember that the whitespace is important, and it's a key-value structure - so your values can either be strings, or substructures - not both.
Also, that yaml validator... I can't seem to make it declare anything as invalid!

Rspec - Using variable defined in a let statement in another let statement

In my RSpec test, I have defined multiple methods using let() syntax. I have encountered a scenario where I need to use variable defined inside a let statement into another let statement inside same describe block.
context 'Reuse the name of first car in the second car' do
it_behaves_like 'some car test' do
let(:car1) do {
name1: "#{testcase['Car']}_#{Time.now.round}",
car_model: testcase['Toyota']
}
end
let(:car2) do {
name2: name1
}
end
end
end
As you can see I want to use the exact name value I defined name1 inside :car1 for name2 inside :car2. The above syntax throws me following error
NameError:
undefined local variable or method `name1' for #<RSpec::
How do I use exact value of name1 in :car2? Any ideas..
let(:name1) { "#{testcase['Car']}_#{Time.now.round}" }
let(:car1) { { name1: name1, car_model: testcase['Toyota'] } }
let(:car2) { { name2: name1 } }
So name1 is also now a lazy variable to initialized when is called, if not for car1, then for car2.
If the Time.now is a problem, you can leave the value of name1 as testcase['Car'] and then just interpolate the value of Time.now.
name1 is a key in the hash defined as car1, therefore you need to use the hash syntax to get its value:
let(:car1) do
{
name1: "#{testcase['Car']}_#{Time.now.round}",
car_model: testcase['Toyota']
}
end
let(:car2) do
{
name2: car[:name1]
}
end
Please note that this only answers your question on how to extract the value, I do not suggest writing specs like that. If both cars should share the same name than Sebastian's answer is probably clearer and easier to understand.
let definitions work just fine with each other.
You defined two things: car1 and car2.
Code is throwing an error about name1. You just didnt define it.
I guess you need to read more about ruby Hash and Symbol.

NSLocalizedString should be used directly for exporting XLIFF?

I used to use NSLocalizedString by custom function.
For example, to access Profile.strings, I define this function:
func LocalizedProfile(key: String, comment: String?) {
NSLocalizedString(key, tableName: "Profile", comment: comment ?? "")
}
And, called like this:
let localized = LocalizedProfile("Submit", comment: "For registration")
This method works fine except for exporting XLIFF.
On the Xcode 6.3.2, executting Export for localizationthrows error:
To get error information, I executed via command line:
xcodebuild -exportLocalizations -localizationPath ./xliff -project MyApp.xcodeproj -exportLanguage ja
And, I got this error:
Bad entry in file /Users/mono/Documents/Git/MyApp/Localization.swift (line = 29): Argument is not a literal string.
Defining custom localization method is very useful for me, but I also want to use exporting XLIFF feature.
Are there any methods to resolve this demands?
Export For Localization and xcodebuild -exportLocalizations both generate strings files by looking for invocations of NSLocalizedString(_:tableName:bundle:value:comment:) in code and uses the static values passed into the parameters to create the appropriate strings files.
This means that the only values you can pass into key, comment, value, and tableName are string literals.
Since you're using a wrapper function around NSLocalizedString(_:comment:) to localize your strings, the only time Xcode sees you calling NSLocalizedString(_:comment:) is in that one wrapper function with non-string-literal values, which is invalid.
What you really want to do instead is call NSLocalizedString(_:tableName:comment:) directly.
Alternatively, you can call Bundle.localizedString(forKey:value:table:) in your wrapper function, but then you have to manually create your own strings files for those key-value pairs.
/// - parameter comment: This value is ignored, but should be provided for
/// context at the call site about the requested localized string.
func LocalizedProfile(key: String, comment: String?) -> String {
return Bundle.main.localizedString(forKey: key, value: nil, table: "Profile")
}

Underscore.js Case Insensitive Sorting

Having some slight issues trying to get underscore.js to do case-insensitive sorting. I have an array of objects and would like to be able to sort by property name.
Using shortcut method sortBy
iteratee may also be the string name of the property to sort by (eg. length).
Array to be sorted:
var array = [{ name: 'test_1234', description: 'zzaaa bb cc'},
{ name: 'zz1111', description: 'ZAAbbbcc'},
{ name: 'TEST', description: '4422'},
{ name: '1a2929', description: 'abcdef'},
{ name: 'abc', description: 'Full description'},
{ name: 'GGGGH', description: '123456'}];
Sorting using this method, sortProperty = 'name', the result places uppercase before lowercase.
var sorted = _.sortBy(array, sortProperty);
1a2929 - abcdef
GGGGH - 123456
TEST - 4422
abc - Full description
test_1234 - zzaaa bb cc
zz1111 - ZAAbbbcc
I assume this has to do with case sensitivity, but I can't figure out how to change names in the array to lowercase and compare that way.
Any help is greatly appreciated.
Edit:
As pointed out, you pass in name or a function, so just adjusted function to return which field to sort by:
http://jsfiddle.net/rjaqp1vg/5/
The name to sort by can be the field name OR a function, so pass a function that does a lower-case conversion.
var sorted = _.sortBy(array, function (i) { return i.name.toLowerCase(); });
should do the trick.
Don't use _.sortBy for this. The correct way to sort strings alphabetically is to use localeCompare. Here's an example in pure Javascript:
['Z', 'A','z','á', 'V'].sort(function(a, b){
return a.localeCompare(b, undefined /* Ignore language */, { sensitivity: 'base' })
});
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare.
Chris' answer worked well for me, and I made it a little shorter with an arrow function:
var sorted = _.sortBy(array, (i) => i.name.toLowerCase());

Resources