nuget modify text content file at installation - visual-studio

I'm writing a nuget package which deploys some content files.
I'd like them to be modified to contain the version number and install path.
I found this but it appears to modify only config and source files.
I noticed install.ps1 scripts, but they look only able to transform the target project and it's elements.
What if I want to add a text file to the project:
You just installed package $packageName version $version in $installPath
transformed after installation in
You just installed package myPackage version 1.0.12.12 in packages/myPackage-1.0.12.12

In fact install.ps1 script is run after the content files copy. And It's run after the content files have been appended to csproj:
Added file 'myfile.txt' to folder 'mypackage\content'.
Added file 'mypackage.nupkg' to folder 'mypackage'.
Successfully installed 'mypackage'.
Added file 'myfile.txt'.
Added file 'myfile.txt' to project 'myproject'
>> PowerShell scripts are being executed from 'tools' (not framework-specific)
Executing script file 'init.ps1`
That means, you can edit whatever your static files from that script (accessing them) from the $project parameter~:
param($installPath, $toolsPath, $package, $project)
$myFile = $project.ProjectItems.Item("myfile.txt")
$filePath = $myFile.Document.FullName
$content = Get-Content -Path "$filePath"
I don't know the canonical way to get the package version from this script, but it's part of the $installPath parameter.
Hope this will help someone

Related

How to create a Zip file using gradle 2.3

I have my archive at location myProject/unzip and need to:
Zip the contents within the unzip folder and create a zip file with some name at any location within the project.
Using gradle 2.3.
Can anyone help me for this?
I am not sure what you are doing differently than the examples in the documentation from the link I gave in the comments. But this works for me with Gradle 2.3:
task myZip(type: Zip){
from "$projectDir/unzip"
archiveName = "my-zip.zip"
destinationDir = buildDir
}
The input folder is called unzip and needs to present as a child in the project folder. It outputs a file my-zip.zip in the build folder.
Be sure that there actually are some resources located in the from path, or Gradle might skip it.

Is there anyway to stop MVSC from creating release and debug folders when using form QtCreator?

Whenever I set my build options in Qt for a specific folder and I compile using MVSC it creates a release and debug folder and puts the output exe file inside that folder. If I compile in linux it usually just puts the final executable file in the folder that I specify. Is there a way to get this last behaviour (that is to stop the creation release and debug folder)?
You can set CONFIG -= debug_and_release in your .pro file and it will stop doing so.
With qmake you can actually specify a destination directory for your binary(ies), and other generated output as well. For example:
DESTDIR = $${OUT_PWD}/bin # this is where the binaries ('target' files) go
OBJECTS_DIR = $${OUT_PWD}/obj # compiled objects
MOC_DIR = $${OUT_PWD}/moc # generated MOC files
UI_DIR = $${OUT_PWD}/ui # generated C++ code from .ui files
RCC_DIR = $${OUT_PWD}/rcc # generated C++ code from .qrc files
OUT_PWD is a built-in variable specifying the current build directory. You could actually use any valid path here.
Reference: http://doc.qt.io/qt-5/qmake-variable-reference.html

Qt Installer project: how to generate package.xml and config.xml

I try to make my Qt Installer project more comfortable.
I need to centralize information about my application and components (config.xml and package.xml) in one file. I don't want to jump on different files with same name and search for changeable elements between xml tags.
My first thougt is doing it right in *.pro file of installer project. I place sections of variables in header of installer project file. But where I need to place the code for xml generating?
What is the better (native / comfortable / crossplatform) way to do this?
The answer is simple here: you cannot generate XML files for Qt Installer: you write them manually, as explained in the documentation.
This section describes the following tasks that you must accomplish to create the installer:
Create a package directory that will contain all the configuration files and installable packages.
Create a configuration file that contains information about how to build the installer binaries and online repositories.
Create a package information file that contains information about the installable components.
Create installer content and copy it to the package directory.
Use the binarycreator tool to create the installer.
However, if you look closer at the examples, you can still generate the installer in the *.pro file. Let's pick an example randomly, System Info:
TEMPLATE = aux
INSTALLER = installer
INPUT = $$PWD/config/config.xml $$PWD/packages
example.input = INPUT
example.output = $$INSTALLER
example.commands = ../../bin/binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT}
example.CONFIG += target_predeps no_link combine
QMAKE_EXTRA_COMPILERS += example
OTHER_FILES = README
If you want to apply this to your project, I think you'll have to modify the ../../bin/binarycreator line and make it system aware, by changing your PATH. It might be possible to call an external script and parse XML files, and make the substitutions you would like to do, but you'd move the complexity to another place.
Instead of maintaining plain good old XML files, you would be creating something between XSLT and XML. Maybe you could just write XSLT (or XSL or XQUERY) and generate XML but I don't know anyone who is using it anymore. Last time I used it was when I was learning Computer Science a long time ago :)
This is possible using the QMAKE_SUBSTITUTES feature which will substitute qmake variables into the given input files and put the output in the build folder.
This runs at qmake time rather than at build time. If this is suitable then you just need to add a target to copy the generated files from the build dir to your source dir.
If you need it to run at build time then you can create a .pri file containing QMAKE_SUBSTITUTES and a target in the main .pro file that will run qmake on this file during the build process.
Main .pro file:
create_xml.commands += $(QMAKE) $$shell_quote($$PWD/config/generate_xml.pri) $$escape_expand(\n\t)
create_xml.commands += $(COPY) $$shell_quote($${OUT_PWD}/config.xml) $$shell_quote($$PWD/config) $$escape_expand(\n\t)
create_xml.commands += $(COPY) $$shell_quote($${OUT_PWD}/package.xml) $$shell_quote($$PWD/packages/my.app.id/meta) $$escape_expand(\n\t)
create_xml.depends = $$PWD/version.pri
QMAKE_EXTRA_TARGETS += create_xml
generate_xml.pri:
TEMPLATE = aux
message("Generating $$OUT_PWD/config.xml and $$OUT_PWD/package.xml")
# Get the version number
include(version.pri)
APP_VERSION = $$VERSION
QMAKE_SUBSTITUTES += package.xml.in config.xml.in
config.xml.in: Note that you need to escape the quotes.
<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<Installer>
<Name>MyApp</Name>
<Version>$$APP_VERSION</Version>
...

Gradle: getting the root project directory path when starting with a custom build file

The structure of my Gradle project is the following:
Project
├── app
└── build.gradle
├── foo
└── bar.txt
·
·
·
└── build.gradle
Normally to get the absolute path of the foo folder I can just simply do new File('foo').getAbsolutePath() in the root build.gradle file.
But this unfortunately doesn't work if you run the gradle script from outside the project directory, for example doing something like this:
$ trunk/gradlew -b trunk/build.gradle tasks
With the previous command gradle is looking for the foo directory in the parent of the Project, because I started the script from there.
Is there a way to get the absolute path of the Project where the build.gradle is, even if you start your script from another directory? Or is there any other way to get a reference of a directory in the same folder where the script is?
I've tried also with getClass().protectionDomain.codeSource.location.path but it is returning the path to the gradle cache directory.
I got past this problem by ensuring Java userDir was set to the project directory (i.e. project.projectDir) at the top of my build.gradle file, as follows:
System.setProperty( "user.dir", project.projectDir.toString() )
println " project dir: "+ System.getProperty("user.dir");
This can be checked by executing a separate (Groovy) code file such as:
println "User Dir: ${System.getProperty( 'user.dir' )}"
You can output the Gradle project values before and after using these statements.
println "Root project: ${project.rootProject}";
println " rootDir: ${project.rootDir}"
println " projectDir: ${project.projectDir}";
println " project dir: ${System.getProperty("user.dir")}";
If you have sub-projects, projectDir is not the same as rootDir.
This hasn't fixed my actual problem but it has ensured that I'm opening the correct file (relative to the location of build.gradle.
new File('foo') by definition (look at its JavaDoc) makes a path relative to the current working directory, so depends on where you call the app from. If you want a path relative to the project folder, use project.file('foo'), or as project is the default for resolving the method just file('foo') and you get the relative path resolved against the project directory, not the working directory. So use file('foo').absolutePath and you will be fine.
In the build.gradle file just use projectDir to get the absolute path of the build.gradle file. from there you can navigate your project's files. read this for more info:
https://www.tutorialspoint.com/gradle/gradle_build_script.htm
I was using new File() and path to get the source directory into the gradle file but in Macbook with M1 Chip it's not working, let me share the code for previous and new version:
Older code:
new File("app/src/")
Updated code:
new File(project.projectDir.getAbsolutePath() + "/src/")

How do you extract a version number from nuspec into TeamCity?

How do you extract a version number from nuspec into TeamCity?
We have a csproj file with this corresponding nuspec node:
1.3.2
In TeamCity I'd like to do a build of this project and create a NuGet package with version 1.3.2.%build.counter%. For example, 1.3.2.322. It is important the version number is coming from a file within source control (the NuSpec) and I don't want to duplicate this as a variable in TeamCity. Is there a way to extract 1.3.2 from the NuSpec file and use it as a TeamCity variable?
This approach works with version 10+ of TeamCity and gets around issues with Select-Xml and namespaces.
$Version = ([xml](Get-Content .\MyProject.nuspec)).package.metadata.version
$BuildCounter = %build.counter%
echo "##teamcity[setParameter name='PackageVersion' value='$Version.$BuildCounter']"
A couple of approaches I can think of spring to mind, both using TeamCity service messages:
Use a PowerShell build step, something like this (apologies my PS isn't great):
$buildcounter = %build.counter%
$node = Select-Xml -XPath "/package/metadata/version" -Path /path/to/nuspec.nuspec
$version = $node.Node.InnerText
Write-Output "##teamcity[buildNumber '$version.$buildcounter']"
Or, similarly, bootstrap a tool like XmlStarlet:
$buildcounter = "1231"
$version = xml sel -T -t -v "/package/metadata/version" Package.nuspec
Write-Output "##teamcity[buildNumber '$version.$buildcounter']"
This step would need to be added before any other step requiring the build number.

Resources