2016-08-05 10 views
5

Ich kann mich nicht erinnern, wo aber ein Beispiel gefunden, wie Ordner von der Suche auszuschließen. Unser Problem war Suche node_modules würde lange Weg Ausnahmen verursachen.Breaking Änderung in GetFiles mit 0.15.2 kann Ordner nicht ausschließen

Func<IFileSystemInfo, bool> exclude_node_modules = fileSystemInfo=>!fileSystemInfo.Path.FullPath.Contains("node_modules"); 

var solutions = GetFiles("./**/*.sln", exclude_node_modules); 

Jede Hilfe zur Lösung dieses Problems wäre hilfreich.

+0

Das Beispiel ist hier: http://cakebuild.net/api/Cake.Common.IO/GlobbingAliases/2CDC8B98 Ich war wirklich glücklich, es zu finden, da es aussah, um das genaue Problem zu lösen, das ich hatte (node_modules). Vielleicht müssen die Dokumente aktualisiert werden, wenn sie das Problem nicht lösen? –

Antwort

3

Um das rekursive Gehen des Dateisystems zu beschleunigen, verwendet Cake die eingebauten .NET-Funktionen, die durch das alte 260-Zeichen-Limit von Windows begrenzt werden. Also, wenn es in den meisten Anwendungsfällen eine Größenordnung schneller ist, scheitert es an zu tiefen Ordnerstrukturen, wie sie Knotenmodule einführen können.

Sie können dies lösen, indem Sie Ordner für Ordner durchlaufen und Prädikate auf den auszuschließenden Ordner anwenden, bevor Sie ihn eingeben.

In meinem Beispiel der folgende Ordnerstruktur verwendet wird

Repo directory 
    | build.cake 
    | test.sln 
    | 
    \---src 
     | test.sln 
     | 
     +---proj1 
     | | test.sln 
     | | 
     | \---node_modules 
     |   node.sln 
     | 
     +---proj2 
     | | test.sln 
     | | 
     | \---node_modules 
     |   node.sln 
     | 
     +---proj3 
     | | test.sln 
     | | 
     | \---node_modules 
     |   node.sln 
     | 
     \---proj4 
      | test.sln 
      | 
      \---node_modules 
        node.sln 

Was wir wollen, ist es, alle Lösungen zu finden rekursiv aus Repo-Verzeichnis nicht das node_modules Verzeichnis eingeben und nicht die node.sln

der Suche nach unten vorgeschlagen wird Lösung hierfür wäre, eine Hilfsmethode namens RecursiveGetFile zu erstellen, die dies für Sie tut:

// find and iterate all solution files 
foreach(var filePath in RecursiveGetFile(
    Context, 
    "./", 
    "*.sln", 
    path=>!path.EndsWith("node_modules", StringComparison.OrdinalIgnoreCase) 
    )) 
{ 
    Information("{0}", filePath); 
} 


// Utility method to recursively find files 
public static IEnumerable<FilePath> RecursiveGetFile(
    ICakeContext context, 
    DirectoryPath directoryPath, 
    string filter, 
    Func<string, bool> predicate 
    ) 
{ 
    var directory = context.FileSystem.GetDirectory(context.MakeAbsolute(directoryPath)); 
    foreach(var file in directory.GetFiles(filter, SearchScope.Current)) 
    { 
     yield return file.Path; 
    } 
    foreach(var file in directory.GetDirectories("*.*", SearchScope.Current) 
     .Where(dir=>predicate(dir.Path.FullPath)) 
     .SelectMany(childDirectory=>RecursiveGetFile(context, childDirectory.Path, filter, predicate)) 
     ) 
    { 
     yield return file; 
    } 
} 

Der Ausgang dieses Skript so etwas wie

RepoRoot/test.sln 
RepoRoot/src/test.sln 
RepoRoot/src/proj1/test.sln 
RepoRoot/src/proj2/test.sln 
RepoRoot/src/proj3/test.sln 
RepoRoot/src/proj4/test.sln 

Diese führt zum Erlöschen der 260 Zeichen Problem durch Überspringen bekannte Störer sein würde, nicht beheben, wenn andere unbekannte Wege gleiche Problem hat.

+0

Ich würde mich freuen, wenn das Verhalten von GetFiles langsamer wäre, aber in mehr Fällen wie oben funktioniert. Ich erwarte, dass eine Anzahl von Personen z. NPM, und wird anschließend GetFiles-Aufrufe haben. –

+1

Das Cake.LongPath-Modul unterstützt Sie für einen längeren Pfad in Cake. – devlead

+0

Lesen Sie hier mehr: https://github.com/cake-contrib/Cake.LongPath.Module – devlead