Environment variables in ROS YAML file? - yaml

Is there a way to use environment variables in a ROS yaml file that gets loaded during a launch file?
For example,
test.launch:
<launch>
<rosparam command="load" file="example.yaml" />
</launch>
example.yaml:
vehicle_name: "${VEHICLE_NAME}_robot"
I know that you could load the environment variable as a param in the launch file using the <env> or <optenv> tags, but when there are a lot of parameters, it's much neater to have them defined in a separate .yaml file. Is there a recommended way to do this?

The rosparam tag has an attribute subst_value to enable the env, optenv, etc. substitution args for the YAML text when added directly in the launch file. That is the following works:
<launch>
<!-- works -->
<rosparam subst_value="true">
foo: $(env USER)
</rosparam>
</launch>
For ROS Kinetic and later, it also works when using an external YAML file:
<launch>
<rosparam file="/path/to/conf.yaml" subst_value="true" />
</launch>

No, roslaunch just uses PyYAML's .load and PyYaml does not support reading env variables in yaml files.
You could create multiple yaml files different names and load them selectively using env variables in launch files, for example:
<launch>
<rosparam command="load" file="$(optenv VEHICLE_NAME default_vehicle_name)_example.yaml" />
</launch>
`

Related

Does packagesbuild support environment variable defined in the .pkgproj file?

I am trying to use packagesbuild to create packages in MacOS. I want to use generic template with environment variable so that I don't require to create separate pkgproj file for each app but packagesbuild is not able to recognize the environment variable defined in the template file.
After setting the environment variable in the terminal
export APP_PATH='/Users/sachin/Documents/Test/Client/Example.app'
and then using the same environment variable in example.pkgproj
...
<key>PATH</key>
<string>${APP_PATH}</string>
...
then triggering the command packagesbuild using the projectfile
packagesbuild example.pkgproj
getting below eror
ERROR:
Description:
Unable to copy item at path 'APP_PATH' to
'/private/tmp/S2EyTxCb/502/ExampleClient' because the item could not be
found
http://s.sudre.free.fr/Software/Packages/about.html

Variable Substitution in OctopusDeploy

I'm trying to substitute a #{port} variable during by deployment using OctopusDeploy. I am able to do it if I directly add it in my App.Config as follows:
<services>
<service name="SampleService" behaviorConfiguration="ServiceBehaviour">
<host>
<baseAddresses>
<add baseAddress="http://localhost:#{port}/SampleService/" />
</baseAddresses>
</host>
..
</service>
Is there a way I can add a default port here (say 25555, so that developers can use it without replacing #{port} always), but still specify to OctopusDeploy that this particular port has to be modified?
(I'm using multi-tenant deployments)
You can use the XML transform feature of config files in conjunction with Octopus deploy.
Octopus itself can run these transforms. When you compile your code, the app.config is renamed [applicationName].exe.config If you create a file called [applicationName].exe.release.config and add this to your package then you can use the same style of transform, that you would normally use in web.config transforms, in that file. If Octopus sees a file called *.release.config it will run any transforms during the deployment process.
Alternatively This blog contains instructions of extending your project so you can use the transform ability of web.config files in app.config files.
So you could do this several ways. Have the hard coded value in you "base" app.config then have the Octopus Variable as a transform in the app.release.config. When you build and package your code, so long as you use the "release" configuration the transform will fire and the hard coded value will be replaced by your build and added to the package.
Or you could do it the other way round, have the hard coded value in the app.debug.config and the Octopus Variable in the app.config. When a developer runs a debug build the Variable would be replaced by the value in the debug.config.
Octopus supports if and unless in variable substitutions (docs: http://docs.octopusdeploy.com/display/OD/Variable+Substitution+Syntax)
That means you could apply a default with relative ease.
Firstly, if the variable exists, use it:
#{if port}#{port}#{/if}
Secondly, if the variable does not exists, use your default:
#{unless port}25555#{/unless}
So just combine them together:
#{if port}#{port}#{/if}#{unless port}25555#{/unless}
While you create a variable using Project variable template , you have the option to provide a default value.
Check the image in the link - Shows Variable template with default value
Unless overridden the default value is substituted while deployed.
So in this case you could create a #{port} variable add the reference variable to project variable template with default value of 25555, which unless overridden will always substitute to 25555 while deployments .

Wix FileSearch is not returning true for an existing file

I'm using the following FileSearch in my Bootstrapper (Wix 3.9 version), and it always returns false, even when the file exists:
<Wix xmlns="htttp://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
...
<Fragment>
<util:FileSearch Path="%systemdrive%\SomeFile.txt" Varialbe="FileExists" Result="exists"/>
...
The log file has the following line:
File search: *******(some random guid), did not find path: %systemdrive%\SomeFile.txt
Setting numeric variable 'FileExists' to value 0
Am I doing something wrong?
Unfortunately, it's not quite so easy to use a runtime environment variable in that way. You first need to set a WiX property with the environment variable and then use that WiX property inside your Path attribute. So something like this (note the single % prefix):
<SetProperty Id="PROP_SYSTEM_DRIVE" Before="InstallInitialize" Sequence="execute" Value="[%SYSTEMDRIVE]" />
Then you should be able to use it in your FileSearch:
<util:FileSearch Path="[PROP_SYSTEM_DRIVE]\SomeFile.txt" Variable="FileExists" Result="exists"/>

Is it possible to pass variable to WIX localization file?

I need to use variable in WIX localization file WIXUI_en-us.wxl.
I tried use it like this:
<String Id="Message_SomeVersionAlreadyInstalled" Overridable="yes">A another version of product $(var.InstallationVersionForGUI) is already installed</String>
But it doesn't work. And when I declared property and used it this way:
<String Id="Message_SomeVersionAlreadyInstalled" Overridable="yes">A another version of product [InstallationVersionForGUI] is already installed</String>
doesn't work either.
Where was I wrong?
Thanks for help and your time.
Localization strings are processed at link time, so you can't use $(var) preprocessor variables. Using a [property] reference is supported, as long as the place where the localization string is used supports run-time formatting (e.g., using the Formatted field type).
Your second method should work just fine. This is the same method used by the default .wxl files.
For example, in your .wxl file you would declare your string:
<String Id="Message_Foo">Foo blah blah [Property1]</String>
And in your .wxs file, you declare the property. If you wish, you can declare the property to match a WiX variable (which it sounds like you're trying to do)
<Property Id="Property1">$(var.Property1)</Property>
I was trying to get localization file to use variables. Came across this post:
There are different layers of variables in WiX (candle's preprocessor
variables, Light's WixVariables/localization variables/binder
variables, and MSI's properties). Each have different syntax and are
evaluated at different times:
Candle's preprocessor variables "$(var.VariableName)" are evaluated
when candle runs, and can be set from candle's commandline and from
"" statements. Buildtime environment
properties as well as custom variables can also be accessed similarly
(changing the "var." prefix with other values).
Light's variables accessible from the command-line are the
WixVariables, and accessing them is via the "!(wix.VariableName)"
syntax. To access your variable from your commandline, you would need
to change your String to: This build was prepared on
!(wix.BuildMachine)
If you instead need to have the BuildMachine value exist as an MSI
property at installation time (which is the "[VariableName]" syntax)
you would need to add the following to one of your wxs files in a
fragment that is already linked in:
Now, the environment variable COMPUTERNAME always has held the name of
my build machines in the past, and you can access that this way:
$(env.COMPUTERNAME). So, you can get rid of the commandline addition
to light.exe and change your wxs file like this:
<WixProperty Id="BuildMachine" Value="$(env.COMPUTERNAME)"/>
Preprocessor variables $(var.VariableName) are are processed at link time, so ideally you would use [PropertyName] which would be defined on the main Product element.
The issue sometimes is that property is not yet defined, for instance using the product name on the localization file seems not posible.
This solution was done aiming to only type the product name once given "Super product" as product name:
In case of running through visual studio extension:
Project properties -> Build -> Define variables -> "MyProductName=Super product" (No quotes)
In case of runing from cmd or some other place:
On Light.exe, add -d"MyProductName=Super product"
Into the localization .wxl file:
<String Id="Description" Overridable="yes">Description of !(wix.MyProductName)
to make it more interesting</String>
I have an aditional config file .wxi I include on other files to have some vars, for instance, here i had hardcoded the value but now it's harcoded on the variable definition and I use the given value:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<!-- Define the product name preprocesor variable -->
<?define ProductName="!(wix.ProductNameDefVar)" ?>
<!-- From this point, can use the preprocesor var -->
<?define ProductName_x64="$(var.ProductName) (64bit)" ?>
<?define ProductName_x32="$(var.ProductName) (32bit)" ?>
<?define CompanyDirName = "My company name" ?>
</Include>
Finally, the place where the localization value where the localization text was not interpolating, is like this:
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<!-- Include the config file with the preprocesor var -->
<?include $(sys.CURRENTDIR)\Config.wxi?>
<!-- Main product definition -->
<Product Id="$(var.ProductCode)"
Name="$(var.ProductName)"
Language="!(loc.Language)"
Version="$(var.BuildVersion)"
Manufacturer="!(loc.Company)"
UpgradeCode="$(var.UpgradeCode)">
<!-- Package details -->
<!-- Here, Description was not interpolating -->
<Package InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine"
Platform="$(var.Platform)"
Manufacturer="!(loc.Company)"
Description="!(loc.Description)"
Keywords="!(loc.Keywords)"
Comments="!(loc.Comments)"
Languages="!(loc.Language)"
/>
[...]

How to pass an integration property to a batch file with CruiseControlNet?

In the build log of my project, i can see these properties:
<integrationProperties>
<CCNetProject>Gdet_T</CCNetProject>
...
<LastModificationDate>4/6/2010 1:29:04 PM</LastModificationDate>
<LastChangeNumber>10841</LastChangeNumber>
</integrationProperties>
I want to pass the property CCNetProject and LastChangeNumber to a batch file. it works well with CCNetProject, as it can be used in the batch as an environment variable %CCNetProject%.
But it doesn't work with other properties (those are not starting with the CCnet prefix) as LastChangeNumber or LastModificationDate.
I tried to pass it as argument, but it fails !
<exec>
<executable>$(WorkingFolderBase)\MyBatch.bat</executable>
<baseDirectory>$(WorkingFolderBase)\</baseDirectory>
<buildArgs>$(LastModificationDate)</buildArgs>
</exec>
I tried to pass it as environment variable, but it fails:
<exec>
<executable>$(WorkingFolderBase)\MyBatch.bat</executable>
<baseDirectory>$(WorkingFolderBase)\</baseDirectory>
<environment>
<variable>
<name>svn_label</name>
<value>"${LastModificationDate}"</value>
</variable>
</environment>
</exec>
The results is always the same when I display the parameter or variable : empty string or the variable name $(svn_label)
I'm sure it is simple, but ... I can't find ! Any idea ?
CCNET passes the following parameters to external programs:
CCNetArtifactDirectory
CCNetBuildCondition
CCNetBuildDate
CCNetBuildTime
CCNetFailureUsers
CCNetIntegrationStatus
CCNetLabel
CCNetLastIntegrationStatus
CCNetListenerFile
CCNetModifyingUsers
CCNetNumericLabel
CCNetProject
CCNetProjectUrl
CCNetRequestSource
CCNetUser
CCNetWorkingDirectory
As you can see LastIntegrationStatus e.g. is available through CCNetLastIntegrationStatus but LastModificationDate e.g. has no equivalent.
You can pass additional arguments via <buildArgs> or <environment> but inside CCNET configuration you have no access on the integration properties mentioned above. Most people starting with CCNET (including myself) try something like <buildArgs>$(CCNetProject)</buildArgs> and fail.
Have a look on my answer to a similar question.
Sorry I can't provide a better solution.
Update (regarding Thinker's suggestion):
Using $[$CCNetLabel] inside CCNET configuration does not seem to work.
Frankly spoken, I would have been rather surprised, if it had. The configuration is something static whereas CCNetLabel is something dynamic, that potentially changes with every integration build. Assuming you have access to these dynamic properties inside the configuration, the configuration might change with every build. Since changing the configuration means restarting the CCNET server automatically, you would cause a server restart with every build. Not actually a desirable behavior, is it?
ok, found the solution.
Need to use a specific label called SvnRevisionLabeller to retrieve the svn revision.
it is then available via the CCNetLabel environement variable.
http://code.google.com/p/svnrevisionlabeller/
<labeller type="svnRevisionLabeller">
<url>http://mysvnrootproject/trunk</url>
</labeller>

Resources