2016-08-05 9 views
5

Я не могу вспомнить, где, но нашел пример, как исключить папку из поиска. Наша проблема заключалась в том, что поиск node_modules вызывал исключения с длинными дорожками.Нарушение изменения в GetFiles с 0.15.2 не может исключать папки

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

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

Любая помощь для решения этой проблемы была бы полезной.

+0

Пример здесь: http://cakebuild.net/api/Cake.Common.IO/GlobbingAliases/2CDC8B98 Я был очень рад найти его, поскольку он решил решить точную проблему, которую я имел (node_modules). Возможно, документы требуют обновления, если они не решают эту проблему? –

ответ

3

Чтобы ускорить рекурсивную ходьбу файловой системы, Cake использует встроенные функции .NET для этого, но она ограничена старым ограничением 260 символов в Windows. Таким образом, когда в большинстве случаев использования это происходит быстрее, он не работает на слишком глубоких структурах папок, таких как, например, модули узла.

Вы можете решить эту проблему, выполнив итерацию папки по папке и применяя предикат, в какой папке исключить его перед вводом.

В моем примере ниже структура папок используется

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 

То, что мы хотим, чтобы найти все решения рекурсивно из каталога репо, не входящих в каталог node_modules и не найдя node.sln

Ниже предлагается решением для этого было бы создать полезный метод, который называется RecursiveGetFile, который сделает это за вас:

// 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; 
    } 
} 

Вывод этого сценария будет что-то вроде

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 

Это аннулирует 260 обугленного вопрос, пропуская известных производителей неприятности, не исправит, если другие неизвестные пути имеет такой же вопрос.

+0

Я был бы счастлив, если поведение GetFiles по умолчанию было медленнее, но работало в большем количестве случаев, как указано выше. Я ожидаю, что несколько ppl должны использовать, например. NPM, и после этого будут вызваны вызовы GetFiles. –

+1

Модуль Cake.LongPath предоставит вам поддержку более длинного пути в Cake. – devlead

+0

Подробнее здесь: https://github.com/cake-contrib/Cake.LongPath.Module – devlead