MSBuild.Community.Tasks Unzip task makes console output bloat - msbuild

I use the following code to unzip archive with MSBuild Community Task Unzip:
<Target Name="Sandbox">
<Unzip
ZipFileName="text.zip"
TargetDirectory="Unzip" />
</Target>
text.zip contains one file text.txt, its size is 716 bytes.
And I obtain several line on console during file extraction:
...
extracted "text.txt"
extracted "text.txt"
extracted "text.txt"
...
3 times for tiny 716 bytes file!
And for large files Unzip task fills console with much more lines: larger file - more lines.
I had 1 line per file in MSBuild Community Tasks 1.2.0.306, but versions 1.3.0.493 and 1.4.0.42 outputs much more lines for single file.
Is it possible to obtain one line per file in new releases of MSBuild community tasks?
I don't know if such behavior is by new design or a bug.

It's a bug. I reported it to upstream (https://github.com/loresoft/msbuildtasks/pull/26) fixed it and it got merged 9 days ago. Should be corrected in the next release.

Related

MsBuild ClCompile Output Format

TL;DR: In the following MsBuild output, what do the file names (sourceFile1.cpp ~ sourceFileX.cpp) that come after the cl command mean? (scroll down for a link to an actual log file)
ClCompile:
cl.exe <args> <includeDirs> <sourceFile1.cpp sourceFile2.cpp ... sourceFileN.cpp>
sourceFile1.cpp # what do these mean?
sourceFile2.cpp
...
sourceFileX.cpp
The N and X are deliberately different variables.
Long:
Context: I'm modifying CppMicroServices library's CMake configuration to be biicode compatible.
Building with the original configuration produces the above output, with N == X, i.e. all files passed to the cl command are also output on the subsequent lines. This compiles fine on Ubuntu 14.10, and Windows 8.1.
Building using the biicode-modified CMakeLists.txt produces a similar output, but N != X. N is the same for both the biicode output and the original, but X for biicode is a much smaller subset of the source files compared to X from the original.
A full log file of this is here: http://pastebin.com/hRi8WGwN
Lines 56 ~ 100: output that matches the original build target (43 source files passed to cl, 43 lines follow with the same source file names).
Lines 183 ~ 192: output for the bii-specific target (43 source files passed to cl, 8 lines of some source file names, followed by some errors which I assume will be fixed when this is solved).
The biicode specific target builds fine on Ubuntu.
The files in the list are the ones that the compiler is supposed to be compiling. It prints them out one by one as it compiles them. If it encounters any errors while compiling, the errors and a reference to the source file they were encountered in will be interspersed with the list of source files that are being compiled.

Can MSBuild ItemGroup's be chunked?

I've got an ItemGroup that includes source files from my project:
<ItemGroup>
<SourceFiles Include=".\**\*.h;.\**\*.cpp"/>
</ItemGroup>
There are a few hundred source files. I want to pass them to a command line tool in an Exec task.
If I call the command line tool individually for each file:
<Exec Command="tool.exe %(SourceFiles.FullPath)" WorkingDirectory="."/>
Then, it runs very slowly.
If I call the command line tool and pass all of the files in one go:
<Exec Command="tool.exe #(SourceFiles -> '"%(FullPath)"', ' ')" WorkingDirectory="."/>
Then, I get an error if there are too many files (I'm guessing the command line length exceeds some maximum).
Is there a way I can chunk the items so that the tool can be called a number of times, each time passing up to a maximum number of source file names to the tool?
I'm not aware of any mechanism to do that with well known item metadata. What you could do is load all those paths into their own item group and write a custom task that calls the exec task. Writing a custom task is pretty simple, it can be done inline:
http://msdn.microsoft.com/en-us/library/vstudio/dd722601(v=vs.100).aspx

finding a corrupted part from the parts of a split archive

I have 7 files with extensions like xyz.rar.001 - xyz.rar.007 clearly they are parts of a single file. I have all the 7 parts. I join them using a file joiner into a single file xyz.rar and try to unrar them with WINRAR , it says that archive is corrupted It is clear that 1 or 2 parts are corrupted. IS THERE ANY WAY TO FIND THEM ? Please help I don't want to re download all of them NOTE- winrar can detect a corrupt part if the parts were splitted using winrar (with extensions like part1.rar , part2.rar etc. ) but not if they are named as rar.001
Parts .001 - .006 should have the same size. Check if there is a file with a different byte size.
Are there multiple files in the RAR or just the one? With multiple you could run a Test and see which is the first file to fail.
I think it's strange that there is a second tool used to split the RAR archive up. (e.g. HJSplit) This lets me think that .002 could be a RAR archive too. Try opening xyz.rar.001 with WinRAR and test/exctract. It happens more that RAR archives have the extension .001 instead of .rar. An example.
Naming your archives in WinRAR like this can be accomplished by putting "xyz.rar.001" as Archive name on the General tab and checking "Old style volume names" on the Advanced tab.
If I then join the files with HJSplit, I get one .rar file (that is corrupt). When I Test it, it says "Next volume is required". In the diagnostic messages I can see "The required volume is absent" and "CRC failed in X. The file is corrupt"
If there is one file stored inside the RAR and the RAR is indeed just chopped up into 7 pieces, there is no way of telling without additional files such as .sfv or .par2. (unless the RAR does not use compression: you can parse the underlying file for errors and calculate the part where it goes wrong)

The output parameter 'CopiedFiles' of Copy task is returning all the files specified to copy even if it copies nothing given SkipUnchangedFiles="true"

The CopiedFiles parameter is returning all the files that were intended to be copied. But given the fact that SkipUnchangedFiles is set to true and ttask itself is not copying anything as can be seen on command line (no copying message). Why not, then, CopiedFiles is empty?
I need to have CopiedFiles parameter be populated only with files that were actually copied (because they were changed) in order to further copy these files into some other folder. This is to maintain an up-to-date release folder as well as to extract only those files which actually need to be propogated onto UAT/production server.
For reference sake, the copy task code I'm using is given below:
<Copy SkipUnchangedFiles="true"
SourceFiles="#(cfile)"
DestinationFiles="#(cfile->'$(PublishDir)\%(Identity)')">
<Output
TaskParameter="CopiedFiles"
ItemName="Changed" />
</Copy>
<Message Text="changed:#(Changed)" Importance="high" />
Is there a bug in the copy task or this is the intended behavior.
The behavior you are seeing is by design. MSBuild keeps track of file dependencies using task outputs. If it were to do otherwise, anything that relied on the #(Changed) item array as an input would not fully process all of the files it needed in most cases. It will even keep track of properties and items created within targets that don't even execute when Inputs and Outputs are up-to-date, for the same reason. Consider making a different Copy task of your own with an additional output parameter, CopiedFilesCopiedByTask (this naming mirrors the naming and behavior of the ValueSetByTask in the otherwise defunct CreateProperty task).

MSBUILD Executing only Changed SQL Scripts

I need to construct an MSBUILD script executes .SQL Scripts which have changed since last build.
I initially thought that I could copy all scripts from one folder to another using the <Copy> task and using the CopiedFiles <Output> for the copy task. However the copy task returns All files that it Attempted to copy, not actual copied files.
I am able to get MSBUILD to execute SQL Scripts via MSBUILD.ExtensionPack but Im scratching my head on this one
You can do this with a concept known as incremental building. The idea is that you would create a target and then specify the inputs and outputs, which would be files. MSBuild will compare the timestamps of the input files to the output files. If all outputs were created after all outputs then the target is skipped. If all inputs are newer then all the target will be executed for all files. If only a portion are out of date, then only those will be passed to the target. For more info on this see the section Using Incremental Builds in my article Best Practices For Creating Reliable Builds, Part 2.
Also for more resources on MSBuild I have compiled a list at http://sedotech.com/Resources#MSBuild
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="RunScripts">
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks"/>
<PropertyGroup>
<ConnStr>Server=Example;Database=Example;Trusted_Connection=True</ConnStr>
<BuildFolder>Build\</BuildFolder>
</PropertyGroup>
<ItemGroup>
<Scripts Include="*.sql"/>
</ItemGroup>
<Target Name="RunScripts"
Inputs="#(Scripts)"
Outputs="#(Scripts->'$(BuildFolder)%(Filename)%(Extension)')">
<SqlExecute TaskAction="ExecuteScalar"
Files="#(Scripts)"
ConnectionString="$(ConnStr)"/>
<Copy SourceFiles="#(Scripts)"
DestinationFiles="#(Scripts->'$(BuildFolder)%(Filename)%(Extension)')"/>
</Target>
</Project>
Could it be that you copying into an empty destination?
SkipUnchangedFiles
If true, skips the copying of files that are unchanged
between the source and destination. The Copy task considers
files to be unchanged if they have the same size and the
same last modified time.
In your case i suspect that all files are considered changed since they don't exist at the destination.