Update property in a script - nant

In my NAnt script I have a property:
<property name="changed.assemblyinfo" value="false" unless="${property::exists('changed.assemblyinfo')}" />
The property can be set from the command line using the -D switch like below, which works fine:
-D:changed.assemblyinfo=true
However, I also want to be able to update the property from within the script itself depending on some logic in the script i.e:
<property name="changed.assemblyinfo" value="true" />
However, every time I do this I get the error:
Read-only property "changed.assemblyinfo" cannot be overwritten
How do I set a property from within the script?

When you pass a property in on the command line, it is treated as a readonly property. From the docs:
iii. Define a read-only property. This is just like passing in the param on the command line.
<property name="do_not_touch_ME" value="hammer" readonly="true" />
That means that you're unable to update it. In your case, if you both need to be able to supply it from the command line and update it depending on logic means that you'll need to supply a default value on the command line that uses a different name, eg:
<property name="changed.assemblyinfo.default" value="false" unless="${property::exists('changed.assemblyinfo.default')}" />
<property name="changed.assemblyinfo" value="${changed.assemblyinfo.default}" />
So now changed.assemblyinfo will contain either the default value of changed.assemblyinfo.default or the value passed in on the command line, while you're free to overwrite it as normal:
<property name="changed.assemblyinfo" value="true" />

Related

Azure Devops Release XML variables not being replaced

I'm trying to create a release where variables from my library are used to replace values in SetParameters.xml. For replacing I used following task: https://github.com/qetza/vsts-replacetokens-task#readme
In my web.config I have following for my connectionStrings:
<connectionStrings configSource="config\connectionStrings.local.config" />
For deployment, this should use another file, eg:
<connectionStrings configSource="config\connectionStrings.config" />
My parameters.xml looks like this:
<parameter name="Connection Strings Config File Location"
defaultValue="__ConnectionStringsConfigurationFileLocation__">
<parameterEntry kind="XmlFile"
scope="\\Web.config$"
match="/configuration/connectionStrings/#configSource" />
<parameter name="Umbraco Database Connection String"
defaultValue="__UmbracoDatabaseConnectionString__">
<parameterValidation kind="AllowEmpty" />
<parameterEntry kind="XmlFile"
scope="\\config\\connectionStrings.config$"
match="/connectionStrings/add[#name='umbracoDbDSN']/#connectionString" />
The variable ConnectionStringsConfigurationFileLocation is in my library:
After deploying, the value of the configSource in web.config remains untouched. But the value of connectionString in \config\connectionStrings.config is replaced succesfully.
What could be the issue that the web.config is not updating?
Edit: Screenshots tasks:
replace
deploy

Controlling the sequence of events in a Wixtoolset (.msi) installer

I am creating a Microsoft Installer (.msi file) using the Wixtoolset (Windows Installer XML). This installer must automate the installation of an existing .exe program (named installer.exe below) and copy a custom configuration file (named settings.conf below) to the target directory. In addition the installer must modify the configuration file using the InstallFiles command below. But the timing of events is critical. If the executable installer runs too early, it fails or exhibits strange behavior. And if the executable installer run too late in the install sequence, it overwrites my modified configuration file with the generic values. I believe this can be done by assigning a string to the Before or After property value. What Before or After property assignment will allow the executable to run properly but not overwrite the configuration file I moved by the CopyFile element? Here is my Wixtoolset XML code.
<Property Id="CONFIGFOLDER" Value="C:\acme\config" >
<Feature
Id="ConfigurationFile"
Title="Configuration File"
Level="1"
<ComponentRef Id="CMP_ACME_Config_File" />
</Feature>
<DirectoryRef Id="TARGETDIR">
<Component Id="CMP_ACME_Config_File" Guid="">
<File
Id="ACME_Config"
Source="MySettings.conf"
KeyPath="yes"
<CopyFile Id="Copy_ACME_Config"
DestinationProperty="CONFIGFOLDER"
DestinationName="settings.conf" />
</File>
</Component>
</DirectoryRef>
<Binary
Id="InstallerEXE"
SourceFile="installer.exe" />
<CustomAction
Id="Launch_Installer"
BinaryKey="InstallerEXE"
Impersonate="yes"
Execute="deferred"
ExeCommand=""
Return="check" />
<InstallExecuteSequence>
<Custom Action="Launch_Installer"
Before="InstallFiles">
</Custom>
</InstallExecuteSequence>
</Property>
I can't explain exactly why this works but assigning "InstallFiles" to the "After" property in the "Custom" element seems to do the trick.
<InstallExecuteSequence>
<Custom Action="Launch_Installer"
After="InstallFiles">
</Custom>
</InstallExecuteSequence>

Eclipse wrongly formats a Spring p-namespace bean

I am using spring-2.5 (cannot upgrade, product dependency) and I notice a strange behaviour of the Eclipse formatter when I am using the p-namespace notation and some value expression:
If I use the standard way (without p-namespace) like this:
<bean id="ldapConfig" class="org.mycompany.project.config.LDAPConfig">
<property name="ldapServer" value="${ldap.server}" />
<property name="ldapPort" value="${ldap.port}" />
<property name="ldapBindDn" value="${ldap.bindDn}" />
<property name="ldapPass" value="${ldap.password}" />
</bean>
and press the key combination: Ctrl-Shift-F the formatting (e.g indentation) works very well.
Now if I use the p-namespace notation like this:
<bean id="ldapConfig" class="org.mycompany.project.config.LDAPConfig">
<p:ldapServer="${ldap.server}" />
<p:ldapPort="${ldap.port}" />
<p:ldapBindDn="${ldap.bindDn}" />
<p:ldapPass="${ldap.password}"/>
</bean>
When I press the key combination: Ctrl-Shift-F the formatting (e.g indentation)
removed some part of the code
<bean id="ldapConfig" class="org.mycompany.project.config.LDAPConfig">
<p:ldapServer = ldap.server } />
<p:ldapPort = ldap.port } />
<p:ldapBindDn = ldap.bindDn } />
<p:ldapPass = ldap.password } />
</bean>
Is there any incompatibility between the value expressions ( ${variable} ) and the p-namespace, or it is just an Eclipse bug on the XML formatting part?
Bean definition of ldapConfig when using p-namespace is not correct. By using the p-namespace you can use attributes as part of the bean element that describe your property values, instead of using nested elements. More details can be found here.
Assuming you have declared namespace as xmlns:p="http://www.springframework.org/schema/p"
The correct way to use it is:
<bean id="ldapConfig" class="org.mycompany.project.config.LDAPConfig"
p:ldapServer="${ldap.server}"
p:ldapPort="${ldap.port}"
p:ldapBindDn="${ldap.bindDn}"
p:ldapPass="${ldap.password}">
</bean>
Now try CTRL-SHIFT-F

How do I optionally require a command line arguement for Ant?

I'm new to ant, and I want to require a file name if something other than the default target is used, so the calling syntax would be something like this:
ant specifictarget -Dfile=myfile
I'm using the ant contrib package to give me additional functionality, so I have this:
<if>
<equals arg1="${file}" arg2="" />
<then>
<!-- fail here -->
</then>
</if>
My thinking is that if file was not specified it might be equal to the empty string. Obviously, this didn't work, and I'm not finding any examples on google or the right syntax in the manual.
So what syntax should I use?
You don't really need the contrib package. This is more conveniently done using built-in ant capabilities like if/unless and depends. See below:
<target name="check" unless="file" description="check that the file property is set" >
<fail message="set file property in the command line (e.g. -Dfile=someval)"/>
</target>
<target name="specifictarget" if="file" depends="check" description=" " >
<echo message="do something ${file}"/>
</target>
You've got the right idea. The
ant specifictarget -Dfile=myfile
sets Ant Properties from the command line. All you really need is
<property name="file" value=""/>
for your default value. That way if file is not specified, it will be equal to the empty string.
Since properties are not mutable in Ant, you can add this:
<property name="file" value="" />
This will set the property file to an empty string if it hasn't already been set on the command line. Then your equality test will work as you intended.
Alternately, you can use escape the value since ant just spits out the actual text when it can't do a property substitution.
<if>
<equals arg1="${file}" arg2="$${file}" />
<then>
<echo>BARF!</echo>
</then>
</if>

How do I deploy registry keys and values using WiX 3.0?

If I want to create the registry key
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApp
with the string value
EventMessageFile : C:\Path\To\File.dll
how do I define this in my WiX 3.0 WXS file? Examples of what the XML should look like is much appreciated.
You seem to want to create an event log source. If that is the case, you should take a look at the <EventSource> element in the util extension.
Check out this page. An example would be:
<registry action="write"
root"HKLM" key="SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApp"
type="string" value="EventMessageFile : C:\Path\To\File.dll" />
I went with this:
<Component Id="EventLogRegKeys" Guid="{my guid}">
<RegistryKey Id="Registry_EventLog" Root="HKLM" Key="SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApp" Action="create">
<RegistryValue Id="Registry_EventLog_EventSourceDll" Action="write" KeyPath="yes" Name="EventMessageFile" Type="string" Value="C:\Path\To\File.dll" />
</RegistryKey>
</Component>
It would be better to refer to File.dll using file reference syntax, to ensure that the actual path it's installed to is used. Use [#filekey], where filekey is the Id of the File element describing the file.
Use the following under DirectoryRef --> Directory...
<Component Id="RegisterAddReferencesTab32" Guid="D9D01248-8F19-45FC-B807-093CD6765A60"> <RegistryValue Action="write" Id="RegInstallDir32" Key="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Eventlog\Application\MyApp" Root="HKLM" Type="string" Value="C:\Path\To\File.dll" /></Component>