Skip to content

Commit

Permalink
Carefuly handle cases when the .paket folder is present in .sln file,…
Browse files Browse the repository at this point in the history
… not present, or is empty.

Fixes fsprojects#2512.
  • Loading branch information
fsoikin committed Jul 11, 2017
1 parent bed3657 commit f4f68e4
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 14 deletions.
33 changes: 24 additions & 9 deletions integrationtests/Paket.IntegrationTests/ConvertFromNuGetSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,30 @@ let ``#1922 should remove references to moved analyzers``() =
StringAssert.Contains(@"<Analyzer Include=""..\packages\StyleCop.Analyzers\analyzers\dotnet\cs\StyleCop.Analyzers.CodeFixes.dll"">", projectXml)
StringAssert.Contains(@"<Analyzer Include=""..\packages\StyleCop.Analyzers\analyzers\dotnet\cs\StyleCop.Analyzers.dll"">", projectXml)

[<Test>]
let ``#2161 should put paket.dependencies inside the .paket folder when it's already present in the sln file``() =
let scenario = "i002161-convert-existing-paket-folder"
let testPaketDependenciesFileInSolution scenario expectedFiles =
paket "convert-from-nuget" scenario |> ignore

let expectedLines =
[ yield "Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"\\.paket\", \"\\.paket\", \"{[^}]+}\""
yield "\s*ProjectSection\\(SolutionItems\\) = preProject"
for f in expectedFiles do yield sprintf "\s*%s = %s" f f
yield "\s*EndProjectSection"
yield "EndProject" ]
|> String.concat Environment.NewLine

let slnFileText = File.ReadAllText(Path.Combine(scenarioTempPath scenario, "sln.sln"))

let slnLines = File.ReadAllLines(Path.Combine(scenarioTempPath scenario, "2161.sln"))
let sectionOpenLine = slnLines |> Array.findIndex (fun line -> line.StartsWith "Project" && line.Contains "\".paket\"")
let sectionEndLine = sectionOpenLine + (slnLines |> Seq.skip sectionOpenLine |> Seq.findIndex (fun line -> line.StartsWith "EndProject"))
let depsFileLine = slnLines |> Array.findIndex (fun line -> line.Contains "paket.dependencies")
System.Text.RegularExpressions.Regex.IsMatch(slnFileText, expectedLines)
|> shouldEqual true

[<Test>]
let ``#2161 should put paket.dependencies inside the .paket folder when it's already present in the sln file``() =
testPaketDependenciesFileInSolution "i002161-convert-existing-paket-folder" ["paket.dependencies"]

sectionOpenLine |> shouldBeSmallerThan depsFileLine
sectionEndLine |> shouldBeGreaterThan depsFileLine
[<Test>]
let ``#2512 should put paket.dependencies inside the .paket folder when it's absent in the sln file``() =
testPaketDependenciesFileInSolution "i002512-convert-absent-paket-folder" ["paket.dependencies"]

[<Test>]
let ``#2512 should put paket.dependencies inside the .paket folder that already has files in it``() =
testPaketDependenciesFileInSolution "i002512-convert-paket-folder-with-files" ["paket.dependencies"; "SomeFile"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "proj", "proj.fsproj", "{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x64.ActiveCfg = Debug|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x64.Build.0 = Debug|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x86.ActiveCfg = Debug|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x86.Build.0 = Debug|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|Any CPU.Build.0 = Release|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x64.ActiveCfg = Release|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x64.Build.0 = Release|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x86.ActiveCfg = Release|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="FSharp.NET.Sdk;Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<Import Project="..\.paket\Paket.Restore.targets" />
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26124.0
MinimumVisualStudioVersion = 15.0.26124.0
Project("{6EC3EE1D-3C4E-46DD-8F32-0CC8E7565705}") = "proj", "proj.fsproj", "{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".paket", ".paket", "{75DC0F05-EDD7-4CAD-B88E-9BA4DFCDDAE2}"
ProjectSection(SolutionItems) = preProject
SomeFile = SomeFile
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x64.ActiveCfg = Debug|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x64.Build.0 = Debug|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x86.ActiveCfg = Debug|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Debug|x86.Build.0 = Debug|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|Any CPU.Build.0 = Release|Any CPU
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x64.ActiveCfg = Release|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x64.Build.0 = Release|x64
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x86.ActiveCfg = Release|x86
{5AB9014A-86E7-4A3C-8731-AC5220ABB7F8}.Release|x86.Build.0 = Release|x86
EndGlobalSection
EndGlobal
27 changes: 22 additions & 5 deletions src/Paket.Core/PaketConfigFiles/SolutionFile.fs
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ type SolutionFile(fileName: string) =
content.RemoveRange(index, 4)
| None -> ()

let projectSectionLines =
[ "\tProjectSection(SolutionItems) = preProject";
"\tEndProjectSection" ]

let addPaketFolder () =
let lines =
[sprintf "Project(\"{%s}\") = \".paket\", \".paket\", \"{%s}\"" Constants.SolutionFolderProjectGuid (Guid.NewGuid().ToString("D").ToUpper());
" ProjectSection(SolutionItems) = preProject";
" EndProjectSection";
"EndProject"]
[sprintf "Project(\"{%s}\") = \".paket\", \".paket\", \"{%s}\"" Constants.SolutionFolderProjectGuid (Guid.NewGuid().ToString("D").ToUpper())]
@ projectSectionLines
@ [ "EndProject" ]

let index =
match content |> Seq.tryFindIndex (fun line -> line.StartsWith("Project")) with
Expand All @@ -46,10 +49,24 @@ type SolutionFile(fileName: string) =

let addPaketFiles(paketProjectIndex, length, dependenciesFile, lockFile) =
let projectLines = content.GetRange(paketProjectIndex, length)

// This here is ad-hoc hacky solution to sln ambiguity.
// The problen is that the .sln file may or may not contain a "ProjectSection" within the ".paket" "Project" (see #2161 and #2512).
// When the "ProjectSection" is not there, we need to add it, and then add new files within it.
// A better solution would be to have a proper parser for the .sln file, but that would take too long, and would probably be a waste anyway.
let firstLineInPaketProject = if paketProjectIndex < content.Count-1 then content.[paketProjectIndex+1] else ""
if not (firstLineInPaketProject.Contains "ProjectSection") then
if firstLineInPaketProject.Contains "EndProject" then
// The "Project" is empty => insert "ProjectSection"
content.InsertRange( paketProjectIndex+1, projectSectionLines )
else
// The "Project" is not empty, but also doesn't contain a "ProjectSection" => no idea what this means,
// so just fall back to old behavior and insert new lines at +2 after "Project" start.
()

let add s =
if not <| Seq.exists (fun line -> line = s) projectLines
then content.Insert(paketProjectIndex + 1, s)
then content.Insert(paketProjectIndex + 2, s)

Option.iter (fun lockFile ->
add (sprintf" %s = %s" lockFile lockFile)) lockFile
Expand Down

0 comments on commit f4f68e4

Please sign in to comment.