Shorthand for PowerShell's `ForEach -Parallel` - foreach

In a PowerShell workflow, the following is valid:
$strings='one','two','three'
foreach -parallel($string in $strings)
{
"Hello: $string"
}
A shorhand way of writing this (without the parallel piece) would be:
$strings='one','two','three'
$strings | `
%{
"Hello: $_"
}
Is there a way to use the shorthand version, specifying that it should be run in parallel?

Not that I can see.
% is a default alias for ForEach-Object which is a core cmdlet. foreach -parallel within workflows is a workflow activity that is separate form the cmdlet and only callable within workflows. In this case, you would need to set an alias to foreach -parallel in your workflow to call the workflow activity - but manipulating aliases is disallowed within workflows (source).

Related

Is it possible to set the a variable group scope using DevOps CLI or via REST

I am able to add/modify DevOps release definitions through a combination of CLI and CLI REST methods. The release definition object does not include (as far as I can tell) a property that controls the variable group scope. The release definition itself takes an array of variable group ID's but there is also the scope of the variable group within the context of the release definition. Where is that?
Is there support to access the variable group scope property in the CLI or CLI REST interface? The image below shows the interface from the portal in azure. Selecting the ellipses (...) you can "change scope" where a list of stages is displayed. You than save and then save the release definition.
I captured fiddler output but the body post was huge and not very helpful, I didn't see anything related to a list of scopes. but obviously this can be done. I'm just not sure about doing so via CLI or REST.
Edit: Here is a view of the script. There is no "scope", which should contain a list of environment names, anywhere in the release definition that I can see. Each environment name (aka stage) contains a number of variable groups associated with each environment.
$sourcedefinition = getreleasedefinitionrequestwithpat $reldefid $personalAccesstoken $org $project | select -Last 1
Write-Host "Root VariableGroups: " $sourcedefinition.variableGroups
$result = #()
#search each stage in the pipeline
foreach($item in $sourcedefinition.environments)
{
Write-Host ""
Write-Host "environment name: "$item.name
Write-Host "environment variable groups: "$item.variableGroups
}
To help clarify, the scope I seek cannot be in the environments collection as this is specific to each element (stage). The scope is set at the release definition level for a given variable group (again refer to the image).
I use this API to get the Definitions of my release and find that the values of variableGroups in ReleaseDefinition and in ReleaseDefinitionEnvironment are different when the scopes are different.
Then I think if we want to change the scope via REST API, we just need to change the variableGroups and update the Definitions. We can use this API to update the Definitions.
Edit:
For example, I want to change my scope from Release to Stage, I use the API like below:
PUT https://vsrm.dev.azure.com/{organization}/{project}/_apis/release/definitions?api-version=6.1-preview.4
Request Body: (I get this from the first Get Definitions API Response Body and make some changes to use it)
{
"source":"userInterface",
"revision":6,
...
"lastRelease": {
"id": 1,
...
},
...
"variables":{
},
"variableGroups":[],
"environments":[
{
"name": "Stage 1",
...
"variables":{
},
"variableGroups":[
4
],
...
}
],
...
}
Note:
Please use your own newer revision.
The id value in lastRelease is your release definitionId.
Specify the stage name in environments name.
The variableGroups value in environments is the id of the variable group you want to change scope.

Trying to run a groovy script to populate a string's description, but the script returns no output, what could be the reason?

I'd like to configure a choice parameter in Jenkins.
The parameter I'd like to configure is called CIDR.
I tried using "Extended choice parameter" plugin but to no avail.
What I'm trying to do, is to let the user manually insert the chosen CIDR, considering the CIDRs which are already in use -> I want to run a groovy script to populate the string description with CIDRs which are already in use.
In order to list the already in use CIDRs, I wrote the following Groovy code:
#!/usr/local/bin/groovy
def p = ['/usr/local/bin/aws', 'ec2', 'describe-vpcs'].execute() | 'grep CidrBlock'.execute() | ['awk', '{print $2}'].execute() | ['tr', '-d', '"\\"\\|,"'].execute()
p.waitFor()
println p.text
The script runs properly in terminal:
itai#Itais-MacBook-Pro ~ - $ groovy cidrs.groovy
172.31.0.0/16
172.51.0.0/16
172.51.0.0/16
I even accepted a suspicious signature in Jenkins in-script approvals to allow the script to run.
But when I insert it to the Groovy script section of the string description and run the "build the job with parameters", the string dropdown stays empty.
What am I doing wrong?
Looks trivial issue. Try below.
Change From :
println p.text
To:
return p.text
The reason why the parameter kept being empty is that as it seems, the "Extended Choice Parameter" plugin expects the output to be an array.
Changing the script to the following code solved the issue:
#!/opt/groovy-2.4.12/bin/groovy
def p = ['/usr/bin/aws', 'ec2', 'describe-vpcs'].execute() | 'grep CidrBlock'.execute() | ['awk', '{print $2}'].execute() | ['tr', '-d', '"\\"\\|,"'].execute()
p.waitFor()
def output = []
p.text.eachLine { line ->
output << line
}
output.each {
println it
}
Now the parameter is populated with the available CIDRs.

Writing help for a custom grails script

I am writing a custom grails script. I want custom help, options etc.
According to doc (
http://grails.github.io/grails-doc/latest/guide/commandLine.html#creatingCustomScripts), I just need to do:
description( "Generates a controller that performs CRUD operations and the associated views" ) {
usage "grails generate-all [DOMAIN CLASS]"
flag name:'force', description:"Whether to overwrite existing files"
argument name:'Domain Class', description:'The name of the domain class'
}
However when I add that to my script, I get:
Warning: Error caching created help for /server/scripts/ExecuteDBScript.groovy: No signature of method: ExecuteDBScript.description() is applicable for argument types: (java.lang.String, ExecuteDBScript$_run_closure1) values: [Generates a controller that performs CRUD operations and the associated views, ...]
My script looks like:
includeTargets << grailsScript("_GrailsInit")
description( "Generates a controller that performs CRUD operations and the associated views" ) {
usage "grails generate-all [DOMAIN CLASS]"
flag name:'force', description:"Whether to overwrite existing files"
argument name:'Domain Class', description:'The name of the domain class'
}
/**
* Script to execute the DB script.
*
*/
target(main: "This script executes DB Script") {
...
}
Any ideas?
Documentation is poor, but I found this solution:
includeTargets << grailsScript("_GrailsBootstrap")
USAGE = """
grails script-name [PARAM]
where
PARAM = Description
"""
target (default: "command description") {
//...
}
Your link (http://grails.github.io/grails-doc/latest/guide/commandLine.html#creatingCustomScripts) refers to the latest version of grails, a non-stable version (3.0.0.M2).
Probably you are using the latest stable version, 2.4.4, so the correct docs are here: http://grails.github.io/grails-doc/2.4.4/ref/Command%20Line/create-script.html

How to Add hookups to Powershell script

I have a powershell script called PostPro.ps1.I would like to provide a hookups to this script so
that if there is need one can add functionality before and after execution of PostPro.ps1 script.
Thanks in advance for your help!
Ramani
another way with parameters :
postpro.ps1:
[CmdletBinding()]
Param(
[ScriptBlock]$before,
[ScriptBlock]$after
)
if($before -ne $null){
Invoke-Command $before
}
write-host "hello"
if($after -ne $null){
Invoke-Command $after
}
then one can provide script to execute :
$b={write-host "before"}
$a={write-host 'after' }
PS>.\postpro.ps1 -before $b -after $a
before
hello
after
One way to do this would be to use modules. If you put all of your extension functions in modules in a certain folder with a certain name format, and then each module needs a runBefore and a runAfter function.
In your PostPro.ps1 script you can load the modules like this:
$modules = ls $(Join-Path $hookDir "postPro-extension-*.psm1") |
% { import-Module $_.FullName -AsCustomObject }
This will load all of the files in $hookDir that have a name that looks like postPro-extension-doSomething.psm1. Each module will be stored in a object that will give you access to each modules functions. To run the functions you can just call them on each object as show below.
You can go like this before the main part of the script
$modules | % { $_.runBefore }
and this after the main part of the script
$module | % { $_.runAfter }

grails: guidance on writing scripts, esp for calling existing database-migration scripts

My requirement is to invoke some processing from a Jenkins build server, to determine whether the domain model has changed since the last build. I've come to the conclusion that the way forward is to write a script that will invoke a sequence of existing scripts from the db-migration plugin. Then I can invoke it in the step that calls test-app and war.
I've looked in the Grails doc, and at some of the db-migration scripts, and I find I'm stuck - have no idea where to start trying things. I'd be really grateful if someone could point me at any suitable sources. BTW, I'm a bit rusty in Grails. Started to teach myself two years ago via proof of concept project, which lasted 6 months. Then it was back to Eclipse rich client work. That might be part of my problem, though I never go involved in scripts.
One thing I need in the Jenkins evt is to get hold of the current SVN revision number being used for the build. Suggestions welcome.
Regards, John
Create a new script by running grails create-script scriptname. The database-migration plugins scripts are configured to be easily reused. There are is a lot of shared code in _DatabaseMigrationCommon.groovy and each script defines one target with a unique name. So you can import either the shared script or any standalone script (or multiple scripts) and call the targets like they're methods.
By default the script generated by create-script "imports" the _GrailsInit script via includeTargets << grailsScript("_GrailsInit") and you can do the same, taking advantage of the magic variables that point at installed plugins' directories:
includeTargets << new File("$databaseMigrationPluginDir/scripts/DbmGenerateChangelog.groovy")
If you do this you can remove the include of _GrailsInit since it's already included, but if you don't that's fine since Grails only includes files once.
Then you can define your target and call any of the plugin's targets. The targets cannot accept parameters, but you can add data to the argsMap (this is a map Grails creates from the parsed commandline arguments) to simulate user-specified args. Note that any args passed to your script will be seen by the database-migration plugin's scripts since they use the same argsMap.
Here's an example script that just does the same thing as dbm-generate-changelog but adds a before and after message:
includeTargets << new File("$databaseMigrationPluginDir/scripts/DbmGenerateChangelog.groovy")
target(foo: "Just calls dbmGenerateChangelog") {
println 'before'
dbmGenerateChangelog()
println 'after'
}
setDefaultTarget foo
Note that I renamed the target from main to foo so it's unique, in case you want to call this from another script.
As an example of working with args, here's a modified version that specifies a default changelog name if none is provided:
println 'before'
if (!argsMap.params) {
argsMap.params = ['foo2.groovy']
}
dbmGenerateChangelog()
println 'after'
Edit: Here's a fuller example that captures the output of dbm-gorm-diff to a string:
includeTargets << new File("$databaseMigrationPluginDir/scripts/_DatabaseMigrationCommon.groovy")
target(foo: "foo") {
depends dbmInit
def configuredSchema = config.grails.plugin.databasemigration.schema
String argSchema = argsMap.schema
String effectiveSchema = argSchema ?: configuredSchema ?: defaultSchema
def realDatabase
boolean add = false // booleanArg('add')
String filename = null // argsList[0]
try {
printMessage "Starting $hyphenatedScriptName"
ByteArrayOutputStream baos = new ByteArrayOutputStream()
def baosOut = new PrintStream(baos)
ScriptUtils.executeAndWrite filename, add, dsName, { PrintStream out ->
MigrationUtils.executeInSession(dsName) {
realDatabase = MigrationUtils.getDatabase(effectiveSchema, dsName)
def gormDatabase = ScriptUtils.createGormDatabase(dataSourceSuffix, config, appCtx, realDatabase, effectiveSchema)
ScriptUtils.createAndPrintFixedDiff(gormDatabase, realDatabase, realDatabase, appCtx, diffTypes, baosOut)
}
}
String xml = new String(baos.toString('UTF-8'))
def ChangelogXml2Groovy = classLoader.loadClass('grails.plugin.databasemigration.ChangelogXml2Groovy')
String groovy = ChangelogXml2Groovy.convert(xml)
// do something with the groovy or xml here
printMessage "Finished $hyphenatedScriptName"
}
catch (e) {
ScriptUtils.printStackTrace e
exit 1
}
finally {
ScriptUtils.closeConnection realDatabase
}
}
setDefaultTarget foo

Resources