@@ -92,6 +92,11 @@ module Crack =
9292
9393 exitCode, ( workingDir, exePath, args)
9494
95+ type private CrackErrors =
96+ | CouldNotGetProperties of Inspect.GetResult
97+ | NotASingleResult of list < Result < Inspect.GetResult , Inspect.GetProjectInfoErrors < obj >>>
98+ | GetProjectOptionsErrors of string * ( string list )
99+
95100 type CrackedProjectInfo = {
96101 ProjectFileName : string
97102 TargetPath : string option
@@ -127,45 +132,73 @@ module Crack =
127132 RepositoryCommit : string option
128133 }
129134
130- let crackProjectFile slnDir extraMsbuildProperties ( file : string ) : CrackedProjectInfo =
131-
132- let projDir = Path.GetDirectoryName( file)
133- let projectAssetsJsonPath = Path.Combine( projDir, " obj" , " project.assets.json" )
134- if not ( File.Exists( projectAssetsJsonPath)) then
135- failwithf " project '%s ' not restored" file
135+ let private crackProjectFileAndIncludeTargetFrameworks slnDir extraMsbuildProperties ( file : string ) =
136+ let mapToCrackedProjectInfo ( props : Map < string , string >) file =
137+ let msbuildPropString prop = props |> Map.tryFind prop |> Option.bind ( function s when String.IsNullOrWhiteSpace( s) -> None | s -> Some s)
138+ let msbuildPropBool prop = prop |> msbuildPropString |> Option.bind msbuildPropBool
136139
137- let additionalInfo = [
138- " OutputType"
139- " IsTestProject"
140- " IsPackable"
141- " RepositoryUrl"
142- " UsesMarkdownComments"
143- " FsDocsCollectionNameLink"
144- " FsDocsLogoSource"
145- " FsDocsNavbarPosition"
146- " FsDocsTheme"
147- " FsDocsLogoLink"
148- " FsDocsLicenseLink"
149- " FsDocsReleaseNotesLink"
150- " FsDocsSourceFolder"
151- " FsDocsSourceRepository"
152- " FsDocsWarnOnMissingDocs"
153- " RepositoryType"
154- " RepositoryBranch"
155- " PackageProjectUrl"
156- " Authors"
157- " GenerateDocumentationFile"
158- //Removed because this is typically a multi-line string and dotnet-proj-info can't handle this
159- //"Description"
160- " PackageLicenseExpression"
161- " PackageTags"
162- " Copyright"
163- " PackageVersion"
164- " PackageIconUrl"
165- //Removed because this is typically a multi-line string and dotnet-proj-info can't handle this
166- //"PackageReleaseNotes"
167- " RepositoryCommit"
168- ]
140+ { ProjectFileName = file
141+ TargetPath = msbuildPropString " TargetPath"
142+ IsTestProject = msbuildPropBool " IsTestProject" |> Option.defaultValue false
143+ IsLibrary = msbuildPropString " OutputType" |> Option.map ( fun s -> s.ToLowerInvariant()) |> ((=) ( Some " library" ))
144+ IsPackable = msbuildPropBool " IsPackable" |> Option.defaultValue false
145+ RepositoryUrl = msbuildPropString " RepositoryUrl"
146+ RepositoryType = msbuildPropString " RepositoryType"
147+ RepositoryBranch = msbuildPropString " RepositoryBranch"
148+ FsDocsCollectionNameLink = msbuildPropString " FsDocsCollectionNameLink"
149+ FsDocsSourceFolder = msbuildPropString " FsDocsSourceFolder"
150+ FsDocsSourceRepository = msbuildPropString " FsDocsSourceRepository"
151+ FsDocsLicenseLink = msbuildPropString " FsDocsLicenseLink"
152+ FsDocsReleaseNotesLink = msbuildPropString " FsDocsReleaseNotesLink"
153+ FsDocsLogoLink = msbuildPropString " FsDocsLogoLink"
154+ FsDocsLogoSource = msbuildPropString " FsDocsLogoSource"
155+ FsDocsNavbarPosition = msbuildPropString " FsDocsNavbarPosition"
156+ FsDocsTheme = msbuildPropString " FsDocsTheme"
157+ FsDocsWarnOnMissingDocs = msbuildPropBool " FsDocsWarnOnMissingDocs" |> Option.defaultValue false
158+ UsesMarkdownComments = msbuildPropBool " UsesMarkdownComments" |> Option.defaultValue false
159+ PackageProjectUrl = msbuildPropString " PackageProjectUrl"
160+ Authors = msbuildPropString " Authors"
161+ GenerateDocumentationFile = msbuildPropBool " GenerateDocumentationFile" |> Option.defaultValue false
162+ PackageLicenseExpression = msbuildPropString " PackageLicenseExpression"
163+ PackageTags = msbuildPropString " PackageTags"
164+ Copyright = msbuildPropString " Copyright"
165+ PackageVersion = msbuildPropString " PackageVersion"
166+ PackageIconUrl = msbuildPropString " PackageIconUrl"
167+ RepositoryCommit = msbuildPropString " RepositoryCommit" }
168+
169+ let additionalInfo =
170+ [ " OutputType"
171+ " IsTestProject"
172+ " IsPackable"
173+ " RepositoryUrl"
174+ " UsesMarkdownComments"
175+ " FsDocsCollectionNameLink"
176+ " FsDocsLogoSource"
177+ " FsDocsNavbarPosition"
178+ " FsDocsTheme"
179+ " FsDocsLogoLink"
180+ " FsDocsLicenseLink"
181+ " FsDocsReleaseNotesLink"
182+ " FsDocsSourceFolder"
183+ " FsDocsSourceRepository"
184+ " FsDocsWarnOnMissingDocs"
185+ " RepositoryType"
186+ " RepositoryBranch"
187+ " PackageProjectUrl"
188+ " Authors"
189+ " GenerateDocumentationFile"
190+ //Removed because this is typically a multi-line string and dotnet-proj-info can't handle this
191+ //"Description"
192+ " PackageLicenseExpression"
193+ " PackageTags"
194+ " Copyright"
195+ " PackageVersion"
196+ " PackageIconUrl"
197+ //Removed because this is typically a multi-line string and dotnet-proj-info can't handle this
198+ //"PackageReleaseNotes"
199+ " RepositoryCommit"
200+ " TargetFrameworks"
201+ ]
169202 let gp () = Inspect.getProperties ( " TargetPath" :: additionalInfo)
170203
171204 let loggedMessages = System.Collections.Concurrent.ConcurrentQueue< string>()
@@ -182,50 +215,48 @@ module Crack =
182215 let result = file |> Inspect.getProjectInfos loggedMessages.Enqueue msbuildExec [ gp] []
183216
184217 let msgs = ( loggedMessages.ToArray() |> Array.toList)
185- //printfn "msgs = %A" msgs
186218 match result with
187- | Ok [ Ok ( Inspect.GetResult.Properties props)] ->
188- let props = readOnlyDict props
189- //printfn "props = %A" (Map.toList props)
190- let msbuildPropString prop =
191- match props.TryGetValue prop with
192- | false , _ -> None
193- | true , s when String.IsNullOrWhiteSpace s -> None
194- | true , s -> Some s
195- let msbuildPropBool prop = prop |> msbuildPropString |> Option.bind msbuildPropBool
219+ | Ok [ gpResult] ->
220+ match gpResult with
221+ | Ok ( Inspect.GetResult.Properties props) ->
222+ let props = props |> Map.ofList
223+ //printfn "props = %A" (Map.toList props)
224+ let msbuildPropString prop = props |> Map.tryFind prop |> Option.bind ( function s when String.IsNullOrWhiteSpace( s) -> None | s -> Some s)
225+ let splitTargetFrameworks = function Some ( s: string) -> s.Split( " ;" , StringSplitOptions.RemoveEmptyEntries) |> Array.map ( fun s' -> s'.Trim()) |> Some | _ -> None
226+ let targetFrameworks = msbuildPropString " TargetFrameworks" |> splitTargetFrameworks
227+
228+ Ok ( targetFrameworks, mapToCrackedProjectInfo props file)
229+ | Ok gp -> CouldNotGetProperties gp |> Result.Error
230+ | Error err-> GetProjectOptionsErrors ( string err, msgs) |> Result.Error
231+ | Ok gps -> NotASingleResult gps |> Result.Error
232+ | Error err-> GetProjectOptionsErrors ( string err, msgs) |> Result.Error
196233
197- {
198- ProjectFileName = file
199- TargetPath = msbuildPropString " TargetPath"
200- IsTestProject = msbuildPropBool " IsTestProject" |> Option.defaultValue false
201- IsLibrary = msbuildPropString " OutputType" |> Option.map ( fun s -> s.Equals( " library" , StringComparison.OrdinalIgnoreCase)) |> Option.defaultValue false
202- IsPackable = msbuildPropBool " IsPackable" |> Option.defaultValue false
203- RepositoryUrl = msbuildPropString " RepositoryUrl"
204- RepositoryType = msbuildPropString " RepositoryType"
205- RepositoryBranch = msbuildPropString " RepositoryBranch"
206- FsDocsCollectionNameLink = msbuildPropString " FsDocsCollectionNameLink"
207- FsDocsSourceFolder = msbuildPropString " FsDocsSourceFolder"
208- FsDocsSourceRepository = msbuildPropString " FsDocsSourceRepository"
209- FsDocsLicenseLink = msbuildPropString " FsDocsLicenseLink"
210- FsDocsReleaseNotesLink = msbuildPropString " FsDocsReleaseNotesLink"
211- FsDocsLogoLink = msbuildPropString " FsDocsLogoLink"
212- FsDocsLogoSource = msbuildPropString " FsDocsLogoSource"
213- FsDocsNavbarPosition = msbuildPropString " FsDocsNavbarPosition"
214- FsDocsTheme = msbuildPropString " FsDocsTheme"
215- FsDocsWarnOnMissingDocs = msbuildPropBool " FsDocsWarnOnMissingDocs" |> Option.defaultValue false
216- UsesMarkdownComments = msbuildPropBool " UsesMarkdownComments" |> Option.defaultValue false
217- PackageProjectUrl = msbuildPropString " PackageProjectUrl"
218- Authors = msbuildPropString " Authors"
219- GenerateDocumentationFile = msbuildPropBool " GenerateDocumentationFile" |> Option.defaultValue false
220- PackageLicenseExpression = msbuildPropString " PackageLicenseExpression"
221- PackageTags = msbuildPropString " PackageTags"
222- Copyright = msbuildPropString " Copyright"
223- PackageVersion = msbuildPropString " PackageVersion"
224- PackageIconUrl = msbuildPropString " PackageIconUrl"
225- RepositoryCommit = msbuildPropString " RepositoryCommit"
226- }
227- | Ok ok -> failwithf " huh? ok = %A " ok
228- | Error err -> failwithf " error - %O \n log - %s " err ( String.concat " \n " msgs)
234+ let crackProjectFile slnDir extraMsbuildProperties ( file : string ) : CrackedProjectInfo =
235+
236+ let projDir = Path.GetDirectoryName( file)
237+ let projectAssetsJsonPath = Path.Combine( projDir, " obj" , " project.assets.json" )
238+ if not ( File.Exists( projectAssetsJsonPath)) then
239+ failwithf " project '%s ' not restored" file
240+
241+ let result = crackProjectFileAndIncludeTargetFrameworks slnDir extraMsbuildProperties file
242+ //printfn "msgs = %A" msgs
243+ match result with
244+ | Ok ( Some targetFrameworks, crackedProjectInfo) when crackedProjectInfo.TargetPath.IsNone && targetFrameworks.Length > 1 ->
245+ // no targetpath and there are multiple target frameworks
246+ // let us retry with first target framework specified:
247+ let extraMsbuildPropertiesAndFirstTargetFramework = Seq.append extraMsbuildProperties [ sprintf " TargetFramework=%s " targetFrameworks.[ 0 ]]
248+ let result2 = crackProjectFileAndIncludeTargetFrameworks slnDir extraMsbuildPropertiesAndFirstTargetFramework file
249+ match result2 with
250+ | Ok (_, crackedProjectInfo) ->
251+ crackedProjectInfo
252+ | Error ( CouldNotGetProperties ok) -> failwithf " huh? ok = %A " ok
253+ | Error ( GetProjectOptionsErrors ( err, msgs)) -> failwithf " error - %s \n log - %s " ( err.ToString()) ( String.concat " \n " msgs)
254+ | Error ( NotASingleResult ok) -> failwithf " huh? ok = %A " ok
255+ | Ok (_, crackedProjectInfo) ->
256+ crackedProjectInfo
257+ | Error ( CouldNotGetProperties ok) -> failwithf " huh? ok = %A " ok
258+ | Error ( GetProjectOptionsErrors ( err, msgs)) -> failwithf " error - %s \n log - %s " ( err.ToString()) ( String.concat " \n " msgs)
259+ | Error ( NotASingleResult ok) -> failwithf " huh? ok = %A " ok
229260
230261 let getProjectsFromSlnFile ( slnPath : string ) =
231262 match InspectSln.tryParseSln slnPath with
0 commit comments