From d7b1fbbd650cccd487a4f76e67f83b409609151d Mon Sep 17 00:00:00 2001 From: Matthias Dittrich Date: Fri, 18 May 2018 20:32:00 +0200 Subject: [PATCH] Fix errors on production deployment - Test production deployment with fake-staging github user & repository on staging - Fix https://github.com/fsharp/FAKE/issues/1750 - Fix another issue with globbing when the base directory name is a substring of the directory to glob into. --- build.fsx | 21 ++++------ src/app/Fake.IO.FileSystem/Globbing.fs | 30 +++++++++---- .../Fake.Core.UnitTests/Fake.IO.Globbing.fs | 42 +++++++++++++++---- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/build.fsx b/build.fsx index 6bfe8325070..db722e104d7 100644 --- a/build.fsx +++ b/build.fsx @@ -81,10 +81,7 @@ let projectName = "FAKE" let projectSummary = "FAKE - F# Make - Get rid of the noise in your build scripts." let projectDescription = "FAKE - F# Make - is a build automation tool for .NET. Tasks and dependencies are specified in a DSL which is integrated in F#." let authors = ["Steffen Forkmann"; "Mauricio Scheffer"; "Colin Bull"; "Matthias Dittrich"] -let gitRaw = Environment.environVarOrDefault "gitRaw" "https://raw.github.com/fsharp" - -let gitOwner = "fsharp" -let gitHome = "https://github.com/" + gitOwner +let github_release_user = Environment.environVarOrDefault "github_release_user" "fsharp" // The name of the project on GitHub let gitName = "FAKE" @@ -483,16 +480,16 @@ Target.create "GenerateDocs" (fun _ -> let source = "./help" let docsTemplate = "docpage.cshtml" let indexTemplate = "indexpage.cshtml" - let githubLink = "https://github.com/fsharp/FAKE" + let githubLink = sprintf "https://github.com/%s/%s" github_release_user gitName let projInfo = [ "page-description", "FAKE - F# Make" "page-author", String.separated ", " authors "project-author", String.separated ", " authors "github-link", githubLink "version", simpleVersion - "project-github", "http://github.com/fsharp/fake" + "project-github", sprintf "http://github.com/%s/%s" github_release_user gitName "project-nuget", "https://www.nuget.org/packages/FAKE" - "root", "http://fsharp.github.io/FAKE" + "root", "https://fake.build" "project-name", "FAKE - F# Make" ] let layoutRoots = [ "./help/templates"; "./help/templates/reference"] @@ -1162,7 +1159,6 @@ Target.create "DotNetCorePushChocolateyPackage" (fun _ -> Target.create "CheckReleaseSecrets" (fun _ -> Environment.environVarOrFail "CHOCOLATEY_API_KEY" |> ignore Environment.environVarOrFail "nugetkey" |> ignore - Environment.environVarOrFail "github_user" |> ignore Environment.environVarOrFail "github_token" |> ignore ) @@ -1286,7 +1282,7 @@ Target.create "ReleaseDocs" (fun _ -> TraceSecrets.register "" s sprintf "%s:x-oauth-basic@" s | _ -> "" - let url = Environment.environVarOrDefault "fake_git_url" (sprintf "https://%sgithub.com/fsharp/FAKE.git" auth) + let url = sprintf "https://%sgithub.com/%s/%s.git" auth github_release_user gitName Git.Repository.cloneSingleBranch "" url "gh-pages" "gh-pages" Git.Repository.fullclean "gh-pages" @@ -1308,8 +1304,8 @@ Target.create "FastRelease" (fun _ -> s | _ -> failwith "please set the github_token environment variable to a github personal access token with repro access." let auth = sprintf "%s:x-oauth-basic@" token - let url = Environment.environVarOrDefault "fake_git_url" (sprintf "https://%sgithub.com/fsharp/FAKE.git" auth) - + let url = sprintf "https://%sgithub.com/%s/%s.git" auth github_release_user gitName + let gitDirectory = Environment.environVarOrDefault "git_directory" "" if not BuildServer.isLocalBuild then Git.CommandHelper.directRunGitCommandAndFail gitDirectory "config user.email matthi.d@gmail.com" @@ -1331,7 +1327,7 @@ Target.create "FastRelease" (fun _ -> |> List.map (fun n -> sprintf "nuget/dotnetcore/Fake.netcore/fake-dotnetcore-%s.zip" n) GitHub.createClientWithToken token - |> GitHub.draftNewRelease gitOwner gitName simpleVersion (release.SemVer.PreRelease <> None) release.Notes + |> GitHub.draftNewRelease github_release_user gitName simpleVersion (release.SemVer.PreRelease <> None) release.Notes |> GitHub.uploadFiles files |> GitHub.publishDraft |> Async.RunSynchronously @@ -1363,6 +1359,7 @@ Target.create "PrepareArtifacts" (fun _ -> Trace.trace "ensure artifacts." let files = !! (artifactsDir "fake-dotnetcore-*.zip") + |> GlobbingPattern.setBaseDir "C:\\" // workaround a globbing bug, remove me with 5.0.0-rc014 |> Seq.toList Trace.tracefn "files: %A" files files diff --git a/src/app/Fake.IO.FileSystem/Globbing.fs b/src/app/Fake.IO.FileSystem/Globbing.fs index c01fcea4a84..c4da98f7995 100644 --- a/src/app/Fake.IO.FileSystem/Globbing.fs +++ b/src/app/Fake.IO.FileSystem/Globbing.fs @@ -100,16 +100,30 @@ let internal getRoot (baseDirectory : string) (pattern : string) = let internal search (baseDir : string) (input : string) = let baseDir = normalizePath baseDir let input = normalizePath input - let input = input.Replace(baseDir, "") + let input = input.Replace(baseDir + string Path.DirectorySeparatorChar, "") let filePattern = Path.GetFileName(input) - input.Split([| '/'; '\\' |], StringSplitOptions.RemoveEmptyEntries) - |> Seq.map (function - | "**" -> Recursive - | a when a = filePattern -> FilePattern(a) - | a when driveRegex.IsMatch a -> Directory(a + "\\") - | a -> Directory(a)) - |> Seq.toList + + let splits = input.Split([| '/'; '\\' |], StringSplitOptions.None) + let baseItems = + let start, rest = + if input.StartsWith "\\\\" && splits.Length >= 4 then + let serverName = splits.[2] + let share = splits.[3] + [ Directory (sprintf "\\\\%s\\%s" serverName share) ], splits |> Seq.skip 4 + else + [], splits |> Array.toSeq + let restList = + rest + |> Seq.filter (String.IsNullOrEmpty >> not) + |> Seq.map (function + | "**" -> Recursive + | a when a = filePattern -> FilePattern(a) + | a when driveRegex.IsMatch a -> Directory(a + "\\") + | a -> Directory(a)) + |> Seq.toList + start @ restList + baseItems |> buildPaths [ baseDir ] |> List.map normalizeOutputPath diff --git a/src/test/Fake.Core.UnitTests/Fake.IO.Globbing.fs b/src/test/Fake.Core.UnitTests/Fake.IO.Globbing.fs index 8e51a8a5ee9..f70b175fc7b 100644 --- a/src/test/Fake.Core.UnitTests/Fake.IO.Globbing.fs +++ b/src/test/Fake.Core.UnitTests/Fake.IO.Globbing.fs @@ -4,8 +4,14 @@ open System.IO open Fake.Core open Fake.IO open Fake.IO.Globbing +open Fake.IO.FileSystemOperators +open Fake.IO.Globbing.Operators open Expecto +open Expecto.Flip open Fake.IO.Globbing.Glob +open System.ComponentModel +open System.ComponentModel +open System.IO let getFileIncludeWithKnownBaseDir includes : LazyGlobbingPattern= { Fake.IO.Globbing.LazyGlobbingPattern.BaseDirectory = @"C:\Project" Fake.IO.Globbing.LazyGlobbingPattern.Includes = includes @@ -22,18 +28,40 @@ let tests = Fake.IO.Globbing.ResolvedGlobbingPattern.Results = [ "folder/file1.exe" "folder/file2.exe" ] } - Expect.equal (globExe.IsMatch "folder/test.exe") true "Glob should match relative paths" - Expect.equal (globExe.IsMatch (Path.GetFullPath "folder/test.exe")) true "Glob should match full paths" + Expect.equal "Glob should match relative paths" true (globExe.IsMatch "folder/test.exe") + Expect.equal "Glob should match full paths" true (globExe.IsMatch (Path.GetFullPath "folder/test.exe")) testCase "It should resolve multiple directories" <| fun _ -> let fileIncludes = getFileIncludeWithKnownBaseDir [@"test1\bin\*.dll"; @"test2\bin\*.dll"] let dirIncludes = GlobbingPattern.getBaseDirectoryIncludes(fileIncludes) - Expect.equal 2 dirIncludes.Length "Should have 2 dirs" - Expect.contains dirIncludes (normalizePath(@"C:\Project\test1\bin")) "Should contain first folder" - Expect.contains dirIncludes (normalizePath(@"C:\Project\test2\bin")) "Should contain second folder" + Expect.equal "Should have 2 dirs" dirIncludes.Length 2 + Expect.contains "Should contain first folder" (normalizePath(@"C:\Project\test1\bin")) dirIncludes + Expect.contains "Should contain second folder" (normalizePath(@"C:\Project\test2\bin")) dirIncludes testCase "should only take the most root path when multiple directories share a root" <| fun _ -> let fileIncludes = getFileIncludeWithKnownBaseDir [@"tests\**\test1\bin\*.dll"; @"tests\test2\bin\*.dll"] let dirIncludes = GlobbingPattern.getBaseDirectoryIncludes(fileIncludes) - Expect.equal 1 dirIncludes.Length "Should have only 1 directory" - Expect.contains dirIncludes (normalizePath(@"C:\Project\tests")) "Should contain tests folder" + Expect.equal "Should have only 1 directory" dirIncludes.Length 1 + Expect.contains "Should contain tests folder" (normalizePath(@"C:\Project\tests")) dirIncludes + + testCase "glob should handle substring directories properly" <| fun _ -> + let testDir = Path.GetTempFileName() + File.Delete testDir + Directory.CreateDirectory testDir |> ignore + try + let name = testDir "Name" + let nameWithSuffix = testDir "NameWithSuffix" + Directory.CreateDirectory name |> ignore + Directory.CreateDirectory nameWithSuffix |> ignore + File.WriteAllText(nameWithSuffix "match1.txt", "match1") + File.WriteAllText(nameWithSuffix "match2.txt", "match2") + File.WriteAllText(nameWithSuffix "match3.txt", "match3") + + !! (nameWithSuffix "match*.txt") + |> GlobbingPattern.setBaseDir name + |> Seq.map (fun f -> Path.GetFileName f) + |> Seq.sort + |> Seq.toList + |> Expect.equal "Expected equal lists." ["match1.txt"; "match2.txt"; "match3.txt"] + finally + Directory.Delete(testDir, true) ]