假 Glob 运算符 (!!) 不扩展目录路径
Fake Glob operator (!!) not expanding directory paths
我有一种情况,在一个假脚本中,我试图使用 Glob (!!) 运算符从一个路径中获取所有单元测试 dll。
问题是在我的机器上 glob 扩展不起作用,在其他类似的 Windows 10 台机器上工作,它很好并找到了 dll。
下面是一个例子:
let path = [function to generate path]
trace path [would look something like "c:\git\project\src\**\*UnitTest*"]
!! path.ToLower()
|> Seq.iter (fun file -> trace file ) [this would not output anything]
我试过很多东西:
- 正在卸载旧版本的 F#
- 正在重新安装最新版本
- 确保 F# 在我的路径中
我使用的软件版本是:
- 假 v4.63.2
- Windows 10
- F#4.1
没有抛出错误或异常。
如果是 F# 或虚假问题,解决问题的最佳方法是什么?
我如何确定 F# Fake 使用的是什么版本?
更新
我重新安装了 F# 4.1 并使用 fsi.exe
和以下命令执行了测试:
Microsoft (R) F# Interactive version 4.1
<snip>
#r @"packages/FAKE/tools/FakeLib.dll";;
open Fake;;
!! "**\*UnitTests.dll" |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
!! "**\*UnitTests.dll".ToLower() |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
已找到所有测试 dll,无论是否调用 ToLower()
。
当我从脚本中删除 ToLower()
后,它现在可以在我的机器上运行了。
但是,在其他人的机器上删除 path
上的 ToLower()
会导致他们找不到任何文件。
那么,Fake 是否使用了不同版本的 fsi.exe
?
我已经打开了一个 github 问题,看看它是否能说明问题:https://github.com/fsharp/FAKE/issues/1772
与所有 .NET 语言一样,在 F# 中,反斜杠用于字符串中的转义序列。
您需要转义反斜杠或使用逐字字符串,例如:
let path = "c:\git\project\src\**\*UnitTest*"
或
let path = @"c:\git\project\src\**\*UnitTest*"
Fake 也可以使用正斜杠:
let path = "c:/git/project/src/**/*UnitTest*"
如果您希望构建脚本在 Linux 上 运行,则无论如何都必须使用正斜杠。
更好的选择是使用相对 路径。您的构建脚本很可能存储在您的项目文件夹中。你可以写
let path = "src/**/*UnitTest*"
使用以下脚本,我能够重现问题并确定问题是由于 Windows 10 如何处理路径中 company
名称的原始大小写。
我通过在文件路径表达式中将 company
名称更改为 **
来确认这一点,操作员工作并找到了所有 dll。
我记得更改了公司名称的大小写,从全部大写变为小写。如果我删除路径上的 ToLower()
,则脚本可以正常工作并找到所有 dll。
这个隐藏的问题,结合 FAKE does a case sensitive search 的方法,也无济于事。
Powershell
packages\FAKE\tools\FAKE.exe glob.test.fsx
glob.test.fsx
#r @"packages/FAKE/tools/FakeLib.dll"
open Fake
let thePath = """C:\git\company/projectname/**/bin/Debug/*UnitTests.dll"""
sprintf "the path is %s" thePath |> trace
!! thePath.ToLower() |> Seq.iter (fun f -> trace f)
我查看了在ProcMon中执行的进程,并没有看到目录的原始大小写。 NTFS 文件系统仍将此目录视为其原始外壳(请参阅下面的注释)。
我每隔几个月就会重新镜像我的机器,所以这很快就会消失,但很高兴了解发生了什么。
感谢所有帮助缩小问题范围的人。
我有一种情况,在一个假脚本中,我试图使用 Glob (!!) 运算符从一个路径中获取所有单元测试 dll。
问题是在我的机器上 glob 扩展不起作用,在其他类似的 Windows 10 台机器上工作,它很好并找到了 dll。
下面是一个例子:
let path = [function to generate path]
trace path [would look something like "c:\git\project\src\**\*UnitTest*"]
!! path.ToLower()
|> Seq.iter (fun file -> trace file ) [this would not output anything]
我试过很多东西:
- 正在卸载旧版本的 F#
- 正在重新安装最新版本
- 确保 F# 在我的路径中
我使用的软件版本是:
- 假 v4.63.2
- Windows 10
- F#4.1
没有抛出错误或异常。
如果是 F# 或虚假问题,解决问题的最佳方法是什么?
我如何确定 F# Fake 使用的是什么版本?
更新
我重新安装了 F# 4.1 并使用 fsi.exe
和以下命令执行了测试:
Microsoft (R) F# Interactive version 4.1
<snip>
#r @"packages/FAKE/tools/FakeLib.dll";;
open Fake;;
!! "**\*UnitTests.dll" |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
!! "**\*UnitTests.dll".ToLower() |> Seq.iter (fun x -> trace x);;
C:\git\project1\bin\Debug\project1.UnitTests.dll
C:\git\project2\bin\Debug\project2.UnitTests.dll
已找到所有测试 dll,无论是否调用 ToLower()
。
当我从脚本中删除 ToLower()
后,它现在可以在我的机器上运行了。
但是,在其他人的机器上删除 path
上的 ToLower()
会导致他们找不到任何文件。
那么,Fake 是否使用了不同版本的 fsi.exe
?
我已经打开了一个 github 问题,看看它是否能说明问题:https://github.com/fsharp/FAKE/issues/1772
与所有 .NET 语言一样,在 F# 中,反斜杠用于字符串中的转义序列。
您需要转义反斜杠或使用逐字字符串,例如:
let path = "c:\git\project\src\**\*UnitTest*"
或
let path = @"c:\git\project\src\**\*UnitTest*"
Fake 也可以使用正斜杠:
let path = "c:/git/project/src/**/*UnitTest*"
如果您希望构建脚本在 Linux 上 运行,则无论如何都必须使用正斜杠。
更好的选择是使用相对 路径。您的构建脚本很可能存储在您的项目文件夹中。你可以写
let path = "src/**/*UnitTest*"
使用以下脚本,我能够重现问题并确定问题是由于 Windows 10 如何处理路径中 company
名称的原始大小写。
我通过在文件路径表达式中将 company
名称更改为 **
来确认这一点,操作员工作并找到了所有 dll。
我记得更改了公司名称的大小写,从全部大写变为小写。如果我删除路径上的 ToLower()
,则脚本可以正常工作并找到所有 dll。
这个隐藏的问题,结合 FAKE does a case sensitive search 的方法,也无济于事。
Powershell
packages\FAKE\tools\FAKE.exe glob.test.fsx
glob.test.fsx
#r @"packages/FAKE/tools/FakeLib.dll"
open Fake
let thePath = """C:\git\company/projectname/**/bin/Debug/*UnitTests.dll"""
sprintf "the path is %s" thePath |> trace
!! thePath.ToLower() |> Seq.iter (fun f -> trace f)
我查看了在ProcMon中执行的进程,并没有看到目录的原始大小写。 NTFS 文件系统仍将此目录视为其原始外壳(请参阅下面的注释)。
我每隔几个月就会重新镜像我的机器,所以这很快就会消失,但很高兴了解发生了什么。
感谢所有帮助缩小问题范围的人。