使用0.15.2打破GetFiles中的更改无法排除文件夹

问题描述:

我不记得在哪里,但找到了一个示例如何从搜索中排除文件夹。我们的问题是搜索node_modules会导致长路径异常。使用0.15.2打破GetFiles中的更改无法排除文件夹

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)的确切问题。如果文档没有解决这个问题,可能文档需要更新? –

为了加速文件系统的递归步骤Cake利用.NET中内置的功能来实现这一功能,但它受限于Windows的旧260字符限制。 因此,当它在大多数用例中速度更快时,它会在太深的文件夹结构上失败,例如节点模块可能会引入。

您可以通过在文件夹中迭代文件夹并在输入文件之前对要排除的文件夹应用谓词来解决此问题。

在我的例子下面的文件夹结构是用来

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