Immer wenn ich mit den Standard Boardmitteln von MSBuild versuche alle Verzeichnisse aufzulisten, so könnte ich verzweifeln. Immer die Verzeichnisse mittels DIR-Befehl in eine Datei schreiben und anschließend mittels ReadLine-Task auslesen.
1 <Exec Command = "dir " $(RefItemsPath) " /b /A:D /S> " $(SourceFolder)\refFolders.bbb " " Condition = "'$(RefItemsPath)'!='' and '$(ReferencePath)'==''" />
2 <Exec Command = "echo $(RefItemsPath)>> " $(SourceFolder)\refFolders.bbb " " Condition = "'$(RefItemsPath)'!='' and '$(ReferencePath)'==''" />
3 <CreateItem Include = "$(SourceFolder)\refFolders.bbb" Condition = "'$(ReferenceFolder)'!='' and '$(ReferencePath)'==''" >
4 <Output TaskParameter = "Include" ItemName = "refs" />
5 </CreateItem>
6 <ReadLinesFromFile File = "@(refs)" Condition = "'$(ReferenceFolder)'!='' and '$(ReferencePath)'==''" >
7 <Output TaskParameter = "Lines" PropertyName = "readedLines" />
8 </ReadLinesFromFile>
Aus meiner Sicht nicht wirklich schön, wenn man nur Verzeichnisse haben möchte, daher habe ich (endlich) einen neuen Task erstellt, da ich immer noch keinen in den CommunityTools gefunden habe. Der Task ist so super einfach, erspart mir aber immer einige Hacks, außerdem werden Build-Files verständlicher.
3 using System;
4 using System . Collections . Generic;
5 using System . Text;
6 using Microsoft . Build . Framework;
7 using Microsoft . Build . Utilities;
8 using System . Xml;
9 using System . IO;
10 using System . Collections;
11 using System . Diagnostics;
12
13 namespace DE . CapeVision . MSBuild . Tasks
14 {
15 public class DiretoryListingTask : Task
16 {
17 private string baseFolder;
18 public bool IncludeSubFolders { get ; set ; }
19 public string SearchPattern { get ; set ; }
20 [ Output ]
21 public string [] FolderContent { get ; set ; }
22 [ Required ]
23 public string BaseFolder
24 {
25 get { return baseFolder; }
26 set { baseFolder = value ; }
27 }
28 public override bool Execute()
29 {
30 //#if(DEBUG)
31 // Debugger.Launch();
32 //#endif
33 if ( ! Directory . Exists( this . baseFolder))
34 return true ;
35 string [] folders = Directory . GetDirectories(
36 this . baseFolder
37 , string . IsNullOrEmpty( this . SearchPattern) ? "*" : this . SearchPattern
38 , this . IncludeSubFolders ? SearchOption . AllDirectories : SearchOption . TopDirectoryOnly
39 );
40 this . FolderContent = folders;
41 return true ;
42 }
43 }
44 }
Das 2. Thema, was ich in dem Zuge angehen wollte, war das Batching mal zu überprüfen. MsBuild ist in der Lage Befehle die mit TaskItems (array) aufgerufen werden zu parallelisieren, bzw. den Befehl immer wieder auszuführen. Das Batching wird mittels des „%“-Operators angekündigt und alles weitere und ggf. Typenkonvertierungen für den Task macht MsBuild. Man kann das sehr gut mit einem einfachen Message-Task testen und nachstellen. Leider hatte meine Ausgabe nie wirklich geklappt, immer wenn 2 Listen verknüpft werden sollten, so kam folgendes raus:
iis ()
---
BROWSER_VIEW
iis () --- LOG_VIEW
iis () --- FILE_VIEW
iis () --- CHANGESET_VIEW
iis () --- TICKET_ADMIN
iis () --- MILESTONE_ADMIN
iis () --- ROADMAP_ADMIN
iis () --- REPORT_ADMIN
iis () --- WIKI_ADMIN
iis () --- TIMELINE_VIEW
iis () --- SEARCH_VIEW
iis () --- TRAC_ADMIN
iis (D:\Cache\Msdn\AdvancedBasics) ---
iis (D:\Cache\Msdn\ContinuousIntegration) ---
iis (D:\Cache\Msdn\DataPoints) ---
iis (D:\Cache\Msdn\DependencyInjection) ---
iis (D:\Cache\Msdn\ExtremeASPNET) ---
iis (D:\Cache\Msdn\Foundations) ---
iis (D:\Cache\Msdn\MVCFramework) ---
iis (D:\Cache\Msdn\OfficeSpace) ---
iis (D:\Cache\Msdn\TestRun) ---
12 <Message Importance = "high" Text = "iis (%(folder.FullPath)) --- %(permission.Identity)" ></Message>
Nach etwas recherche fand ich auch ähnlich Probleme und irgendwo auch eine Lösung (Gute Erklärung http://blogs.msdn.com/aaronhallberg/archive/2006/09/05/msbuild-batching-generating-a-cross-product.aspx). Man muss die Ausgabe mittels MsBuild-Task in 2 Targets teilen, so dass der MsBuild-Tasks als Batch durchlaufen wird und anschließend der 2. Taks. Mein Skript sieht komplett so aus:
1 <?xml version = "1.0" encoding = "utf-8" ?>
2 <Project DefaultTargets = "Test" xmlns = "http://schemas.microsoft.com/developer/msbuild/2003" >
3 <UsingTask AssemblyFile = "DE.CapeVision.MSBuild.Tasks.dll" TaskName = "DE.CapeVision.MSBuild.Tasks.DiretoryListingTask" />
4 <ItemGroup>
5 <permission Include = "BROWSER_VIEW;LOG_VIEW;FILE_VIEW;CHANGESET_VIEW;TICKET_ADMIN;MILESTONE_ADMIN;ROADMAP_ADMIN;REPORT_ADMIN;WIKI_ADMIN;TIMELINE_VIEW;SEARCH_VIEW;TRAC_ADMIN" />
6 </ItemGroup>
7 <Target Name = "Test" >
8 <DiretoryListingTask BaseFolder = "D:\Cache\Msdn" >
9 <Output TaskParameter = "FolderContent" ItemName = "folder" />
10 </DiretoryListingTask>
11 <Message Importance = "high" Text = "iis (%(folder.FullPath)) --- %(permission.Identity)" ></Message>
12 <Message Importance = "high" Text = "second:" ></Message>
13 <MSBuild Projects = "$(MSBuildProjectFile)" Targets = "InternalAddPermission" Properties = "Folder=%(folder.FullPath)" />
14 </Target>
15 <Target Name = "InternalAddPermission" >
16 <Message Importance = "high" Text = "third:" ></Message>
17 <Message Importance = "high" Text = "trac-admin $(folder) permission add tester %(permission.Identity)" ></Message>
18 </Target>
19 </Project>
Gebraucht habe ich beides um die Berechtigungen an den TRAC-Repositories anzupassen, die wir haben. (Dann natürlich nicht mit Message-Task ;))
Keine Kommentare:
Kommentar veröffentlichen