VSTS Nested Variables - azure-devops

I'm trying to accomplish a cascading variable, where when one design time variable is set, it cascades to other variables. Is this possible? I've tried with dot notation, I've tried without dot notation, and I've tried to do it in the task:
I also tried this task plugin, but my agents are on 2.0 and the task doesn't run.
Variable Toolbox Task
Any ideas?
Answer:
You can override these variables at the environment level. I will have to expand these variables in my script manually and then set them to the resolved values in this script.

You can set the variable value through Logging Command during the build:
Add PowerShell task
Script: (Need to use _ instead if the variable contains ., such as Server.Dev=> Server_Dev)
$v= [Environment]::GetEnvironmentVariable("Server_$env:Environment")
Write-Host ("##vso[task.setvariable variable=Server;]$v")
Then the following tasks could use Server variable with corresponding value

Instead of having different variables for each environment, use the same variable but override it at the environment level.

Related

Can I alias the dot sourcing command?

I find myself missing the . in dot sourced files and spending a little time getting my footing when switching from C# to PS. Is there a way to alias the . or use a similar command that is more blatantly noticeable?
In short: No, you cannot define an alias for . :
., the (dot-)sourcing operator, is an operator and as such it cannot be the target of an alias (only commands can).
Defining a function is also not an option, because it would itself have to be dot-sourced when called, in order to be able to dot-source other commands (scripts whose definitions to load into the caller's scope).

Powershell sub-expression syntax used by TFS/Azure Devops

TFS/Azure DevOps allows you to reference custom variables and built in build/release variables using the following syntax:
$(variable_name)
For example, if I wanted to grab the build definition name, I would grab the value from the following sub-expression:
$(Build.DefinitionName)
But, as far as I can tell, the above syntax is not a valid powershell sub-expression.
If "Build.DefinitionName" was a variable, it would need to look like:
$($Build.DefinitionName)
If it were a collection/hashtable, it would use curly braces:
${Build.DefinitionName}
If it were an object with a static property, it would be:
${Build::DefinitionName}
So what the heck is "Build" in the above example? Is TFS/VSTS/Azure DevOps doing some magic string replacement here or something?
It's not a Powershell language element, it's a simple TFS/VSTS placeholder syntax, just like SQLCMD uses: https://learn.microsoft.com/en-us/sql/relational-databases/scripting/sqlcmd-use-with-scripting-variables?view=sql-server-2017
TFS/VSTS inserts the values for these placeholders before invoking your Powershell tasks.
Build/release variables are made available to processes running in the scope of a build/release in the form of environment variables.
As an example, the build definition name is available the same way you'd access any other environment variable in PowerShell: $env:BUILD_DEFINITIONNAME. Note that periods are replaced with underscores.
The exception is secrets. Anything defined as a secret will have to be explicitly passed in to the consuming script, as they are not populated as environment variables.

TFS variable update, variable split

I have a questions about Team Foundation Server variables:
Is there a way to update/define TFS variables from a PowerShell script (runs as a custom build step)?
When I define a variable value like "a,b,c" and I want to use it in a build step which wants it as a multiline value (separated by \n) is there a way to split it online, like Projects: $(myVariable).split(',') ?
Can I define multiline-type variable value?
Variables are name-value pairs defined by you or provided by Build or Release Management. You can use variables as inputs and in your scripts. Check: https://www.visualstudio.com/en-us/docs/build/define/variables
One variable usually has one value. But your requirement should can be achieved with Poswershell script, you need to refer to Powershell documentation to implement how to split values.
No. Never seen such definition.

Eclipse variable substitution syntax rules?

In many environments, variable substitution syntax provides for substituting or testing the final value of the variable.
From bash ${foo#t*is}, for instance, is delete regex t*is in the variable.
Is there anything like this available in eclipse?
Specifically, the variables that the framework uses to control and invoke the underlying tools - the ones you see when you list system variables, environment variable, build environment variables, etc.
Accessing these for use in command line invocations is ${VARIABLE_NAME}, and there is a syntax for modifying them - I have seen ${PROJECT_NAME:MyProject} for example.
The question concerns the documentation and full capability of this ability.

Specify empty variable on make command line

I have some Makefiles that are flexible based on the existence of certain variables by using ifdef to check for them. It is a bit annoying that I have to actually set the variable equal to something on the command line. make all DEBUG does not trigger the ifdef but make all DEBUG=1 does. Perhaps I am just using the C pre-processor approach where it does not belong.
Q1) Is it possible to specify a variable on the command line to be empty? Without even more characters?
Q2) What is the preferred approach for such boolean parameters to a make?
I assume you mean make all DEBUG= here, right? Without the = make will consider DEBUG to be a target to build, not a variable assignment.
The manual specifies that a variable that has a non-empty value causes ifdef to return true. A variable that does not exist or exists but contains the empty string, causes ifdef to return false. Note ifdef does not expand the variable, it just tests whether the variable has any value.
You can use the $(origin ...) function to test whether a variable is really not defined at all, or is defined but empty, like this:
ifeq ($(origin DEBUG),undefined)
$(info Variable DEBUG is not defined)
else
$(info Variable DEBUG is defined)
endif
As #MadScientist explained few minutes ago,
make all DEBUG
adds a target DEBUG to your make. Luckily, there is a workaround:
ifneq (,$(filter DEBUG,$(MAKECMDGOALS)))
DEBUG:=1 # or do whatever you want
DEBUG: all; #echo -n
endif
It is essential to supply a dummy rule (e.g. echo nothing, as above) to the dummy target. And either put this statement at the bottom of your makefile, or specify the prerequisite target explicitly as in the example. Otherwise, make may wrongly choose DEBUG target instead of all.
Note that this is not a preferred approach; the convention is like using V=1 to turn echo on.
Another caveat is that make processes the command-line goals sequentially, e.g. make A B will first take care of A target, then of B target, whether these targets are independent, or depend one on the other. Therefore writing make DEBUG PERFECT and make PERFECT DEBUG could produce different results. But the order of parameters is irrelevant, therefore make PERFECT=1 DEBUG=1 and make DEBUG=1 PERFECT=1 are equivalent.
It is already clarified why you can't use just DEBUG. But I would like to add something.
You can use shell script before running make that setup all variables you need, so, for example in linux shell it will look like this:
$source debug_setup.sh
$make all
Make is starting...
Debug is enabled
...
where debug_setup.sh contains all environment variables you need to set up:
export DEBUG=1
export DEBUG_OPTION=some_option
This is nice since you can make comments there, you can comment out if you don't need something at the moment and would like to keep for the future, etc.
Then you can have several setup scripts that must/can be used as a part of standard routine. This all depends on how many variables you need to set up, how many sets of variables you would like to have, etc.
Note that it is a good idea to notify user somehow which set of variables is selected.