@@ -2,6 +2,7 @@ module Buckaroo.InstallCommand
22
33open System
44open System.IO
5+ open FSharp.Control
56open FSharpx.Control
67open Buckaroo
78open Buckaroo.BuckConfig
@@ -19,35 +20,7 @@ let private fetchManifestFromLock (lock : Lock) (sourceExplorer : ISourceExplore
1920 return ! sourceExplorer.FetchManifest location
2021}
2122
22- let private fetchDependencyTargets ( lock : Lock ) ( sourceExplorer : ISourceExplorer ) ( manifest : Manifest ) = async {
23- let! targetIdentifiers =
24- manifest.Dependencies
25- |> Seq.map ( fun d -> async {
26- let! targets =
27- match d.Targets with
28- | Some targets -> async {
29- return targets |> List.toSeq
30- }
31- | None -> async {
32- let! manifest = fetchManifestFromLock lock sourceExplorer d.Package
33- return manifest.Targets |> Set.toSeq
34- }
35-
36- return
37- targets
38- |> Seq.map ( fun target ->
39- { Package = d.Package; Target = target }
40- )
41- })
42- |> Async.Parallel
43-
44- return
45- targetIdentifiers
46- |> Seq.collect id
47- |> Seq.toList
48- }
49-
50- let private buckarooMacros =
23+ let private buckarooBuckMacros =
5124 [
5225 " def buckaroo_cell(package): " ;
5326 " cell = native.read_config('buckaroo', package, '').strip()" ;
@@ -91,11 +64,24 @@ let rec computeCellIdentifier (parents : PackageIdentifier list) (package : Pack
9164 | head:: tail ->
9265 ( computeCellIdentifier tail head) + " ." + ( computeCellIdentifier [] package)
9366
94- let rec private combinePaths xs =
95- match xs with
96- | [ x ] -> x
97- | x:: xs -> Path.Combine ( x, combinePaths xs)
98- | [] -> " "
67+ let private packageWorkspaceName ( parents : PackageIdentifier list ) ( package : PackageIdentifier ) =
68+ let s =
69+ seq {
70+ yield ! parents
71+ yield package
72+ }
73+ |> Seq.map PackageIdentifier.show
74+ |> String.concat " _"
75+
76+ " buckaroo_" +
77+ (
78+ s
79+ |> Strings.replaceAll [ " /" ; " ." ; " -" ] " _"
80+ ) + " _" +
81+ (
82+ Hashing.sha256 s
83+ |> Strings.truncate 8
84+ )
9985
10086let rec packageInstallPath ( parents : PackageIdentifier list ) ( package : PackageIdentifier ) =
10187 match parents with
@@ -104,7 +90,7 @@ let rec packageInstallPath (parents : PackageIdentifier list) (package : Package
10490 match package with
10591 | PackageIdentifier.GitHub x -> ( " github" , x.Owner, x.Project)
10692 | PackageIdentifier.BitBucket x -> ( " bitbucket" , x.Owner, x.Project)
107- | PackageIdentifier.GitLab x -> ( " gitlab" , combinePaths x.Groups, x.Project)
93+ | PackageIdentifier.GitLab x -> ( " gitlab" , Paths.combineAll x.Groups, x.Project)
10894 | PackageIdentifier.Adhoc x -> ( " adhoc" , x.Owner, x.Project)
10995 String.Join ( " /" , [ Constants.PackagesDirectory; prefix; owner; project ])
11096 | head:: tail ->
@@ -345,65 +331,40 @@ let private generateBuckConfig (sourceExplorer : ISourceExplorer) (parents : Pac
345331 return buckarooConfig |> BuckConfig.render
346332}
347333
348- let private workspaceName ( package : PackageIdentifier ) =
349- " buckaroo_" + ( PackageIdentifier.show package)
350- |> Strings.replace " -" " _"
351- |> Strings.replace " ." " _"
352- |> Strings.replace " /" " _"
353-
354- let private dataBzl ( packages : Map < PackageIdentifier , LockedPackage >) =
334+ let private generateBazelDefs ( targets : Set < TargetIdentifier >) =
355335 seq {
356- yield " packages = {"
336+ yield " def buckaroo_deps():"
337+
338+ yield " return ["
357339 yield !
358- packages
359- |> Map.toSeq
360- |> Seq.collect ( fun ( packageIdentifier , lockedPackage ) -> seq {
361- yield " \" " + ( PackageIdentifier.show packageIdentifier) + " \" : {"
362- yield " \" workspace\" : \" " + ( workspaceName packageIdentifier) + " \" ,"
363- yield " \" path\" : \" " + ( packageInstallPath [] packageIdentifier) + " \" , "
364- yield " }, "
340+ targets
341+ |> Seq.collect ( fun t -> seq {
342+ let parents , package = t.PackagePath
343+ yield " \" @" + ( packageWorkspaceName parents package) + ( Target.show t.Target) + " \" ,"
365344 })
366- yield " }"
345+
346+ yield " ]"
347+
367348 yield " "
368349 }
369350 |> String.concat " \n "
370351
371- let private defsBzl = """
372- load("//:data.bzl", "packages")
373-
374- # Utility function to get the name of the Bazel WORKSPACE at which a package is installed.
375- def buckaroo_workspace(package_name):
376- package = packages.get(package_name)
377- if package:
378- return package.get("workspace")
379- else:
380- fail("The package " + package_name + " could not be found. ")
381-
382- # Utility function to be used in the user's WORKSPACE to wire-up each package.
383- def buckaroo_setup():
384- for package in packages.values():
385- native.local_repository(
386- name = package.get("workspace"),
387- path = package.get("path"),
388- )
389- """
390-
391352let rec private installBuckPackages ( context : Tasks.TaskContext ) ( root : string ) ( parents : PackageIdentifier list ) ( packages : Map < PackageIdentifier , LockedPackage >) = async {
392353 // Prepare workspace
393354 do ! Files.mkdirp root
394355 do ! Files.touch ( Path.Combine( root, " .buckconfig" ))
395356
396357 if File.Exists ( Path.Combine( root, Constants.BuckarooMacrosFileName)) |> not
397358 then
398- do ! Files.writeFile ( Path.Combine( root, Constants.BuckarooMacrosFileName)) buckarooMacros
359+ do ! Files.writeFile ( Path.Combine( root, Constants.BuckarooMacrosFileName)) buckarooBuckMacros
399360
400361 // Install packages
401362 for ( package, lockedPackage) in packages |> Map.toSeq do
402363 let installPath =
403364 Path.Combine( root, packageInstallPath [] package)
404365 |> Paths.normalize
405366
406- let childParents = ( parents @ [ package ])
367+ let childParents = parents @ [ package ]
407368
408369 // Install child package sources
409370 do ! installPackageSources context installPath lockedPackage.Location lockedPackage.Versions
@@ -419,37 +380,113 @@ let rec private installBuckPackages (context : Tasks.TaskContext) (root : string
419380 do ! Files.writeFile ( Path.Combine( installPath, " .buckconfig.d" , " .buckconfig.buckaroo" )) buckarooConfig
420381}
421382
383+ let rec private computeNestedPackages ( parents : PackageIdentifier list ) packages =
384+ packages
385+ |> Map.toSeq
386+ |> Seq.collect ( fun ( k , v ) -> seq {
387+ yield ( parents, k)
388+ yield ! computeNestedPackages ( parents @ [ k ]) v.PrivatePackages
389+ })
390+
391+ let private generateTopLevelBazelDefs ( sourceExplorer : ISourceExplorer ) ( lock : Lock ) = async {
392+ return
393+ seq {
394+ yield " def buckaroo_setup():"
395+
396+ // We need to create a "local_repository" for every package and its private packages
397+ yield !
398+ lock.Packages
399+ |> computeNestedPackages []
400+ |> Seq.collect ( fun ( parents , package ) -> seq {
401+ yield " native.local_repository("
402+ yield " name = \" " + ( packageWorkspaceName parents package) + " \" ,"
403+ yield " path = \" " + ( packageInstallPath parents package) + " \" "
404+ yield " )"
405+ yield " "
406+ })
407+
408+ yield " return None"
409+ yield " "
410+ yield generateBazelDefs lock.Dependencies
411+ }
412+ |> String.concat " \n "
413+ }
414+
422415let rec private installBazelPackages ( context : Tasks.TaskContext ) ( root : string ) ( parents : PackageIdentifier list ) ( packages : Map < PackageIdentifier , LockedPackage >) = async {
423- // Prepare workspace
424- do ! Files.mkdirp root
425- do ! Files.touch ( Path.Combine ( root, " WORKSPACE" ))
416+ do ! Files.touch ( Paths.combine root " WORKSPACE" )
426417
427418 // Install packages
428419 for ( package, lockedPackage) in packages |> Map.toSeq do
429420 let installPath =
430- Path.Combine ( root, packageInstallPath [] package)
421+ Paths.combine root ( packageInstallPath [] package)
431422 |> Paths.normalize
432423
433- let childParents = ( parents @ [ package ])
424+ let childParents = parents @ [ package ]
434425
435426 // Install child package sources
436427 do ! installPackageSources context installPath lockedPackage.Location lockedPackage.Versions
437428
438- // Install child's child (recurse)
429+ // Install child's children (recurse)
439430 do ! installBazelPackages context installPath childParents lockedPackage.PrivatePackages
440431
441- // Write macros
442- do ! Files.writeFile ( Path.Combine ( " buckaroo" , " data.bzl" )) ( dataBzl packages)
443- do ! Files.writeFile ( Path.Combine ( " buckaroo" , " defs.bzl" )) defsBzl
444- }
432+ // Write buckaroo/defs.bzl
433+ do ! Files.mkdirp ( Paths.combineAll [ installPath; Constants.PackagesDirectory ])
434+
435+ do ! Files.touch ( Paths.combineAll [ installPath; Constants.PackagesDirectory; " BUILD.bazel" ])
436+
437+ let! manifest = context.SourceExplorer.FetchManifest ( lockedPackage.Location, lockedPackage.Versions)
438+
439+ let! targets =
440+ asyncSeq {
441+ let xs =
442+ manifest.Dependencies
443+ |> Seq.map ( fun d -> ( parents, d))
444+ |> Seq.append (
445+ manifest.PrivateDependencies
446+ |> Seq.map ( fun d -> ( parents @ [ package ], d))
447+ )
448+
449+ for parents, dependency in xs do
450+ match dependency.Targets with
451+ | Some targets ->
452+ yield !
453+ targets
454+ |> Seq.map ( fun target ->
455+ {
456+ PackagePath = parents, dependency.Package
457+ Target = target
458+ }
459+ )
460+ |> AsyncSeq.ofSeq
461+ | None ->
462+ // If the manifest does not specify any targets then
463+ // we need to take the defaults listed in the package manifest.
464+ let lockedPackage =
465+ packages
466+ |> Map.find dependency.Package // TODO: Better error if this fails. Indicates an invalid lock-file?
467+
468+ let! manifest =
469+ context.SourceExplorer.FetchManifest ( lockedPackage.Location, lockedPackage.Versions)
470+
471+ yield !
472+ manifest.Targets
473+ |> Seq.map ( fun target ->
474+ {
475+ PackagePath = parents, dependency.Package
476+ Target = target
477+ }
478+ )
479+ |> AsyncSeq.ofSeq
480+ }
481+ |> AsyncSeq.toListAsync
482+ |> Async.map Set.ofSeq
483+
484+ let buckarooDefs =
485+ generateBazelDefs
486+ targets
445487
446- let rec private computeNestedPackages ( parents : PackageIdentifier list ) packages =
447- packages
448- |> Map.toSeq
449- |> Seq.collect ( fun ( k , v ) -> seq {
450- yield ( parents, k)
451- yield ! computeNestedPackages ( parents @ [ k ]) v.PrivatePackages
452- })
488+ do ! Files.writeFile ( Path.Combine( installPath, Constants.PackagesDirectory, Constants.BuckarooDefsFileName)) buckarooDefs
489+ }
453490
454491let writeTopLevelBuckFiles ( context : Tasks.TaskContext ) ( root : string ) ( lock : Lock ) = async {
455492 let nestedPackages =
@@ -476,7 +513,7 @@ let writeTopLevelBuckFiles (context : Tasks.TaskContext) (root : string) (lock :
476513 " dependencies" ,
477514 (
478515 lock.Dependencies
479- |> Seq.map ( fun d -> ( computeCellIdentifier [] d.Package ) + ( Target.show d.Target))
516+ |> Seq.map ( fun d -> ( computeCellIdentifier ( fst d.PackagePath ) ( snd d.PackagePath ) ) + ( Target.show d.Target))
480517 |> String.concat " "
481518 |> INIString
482519 )
@@ -493,6 +530,15 @@ let writeTopLevelBuckFiles (context : Tasks.TaskContext) (root : string) (lock :
493530 do ! Files.writeFile ( Path.Combine ( root, " .buckconfig.d" , " .buckconfig.buckaroo" )) ( BuckConfig.render config)
494531}
495532
533+ let writeTopLevelBazelFiles context lock = async {
534+ do ! Files.mkdirp ( Paths.combine " ." Constants.PackagesDirectory)
535+ do ! Files.touch ( Paths.combineAll [ " ." ; Constants.PackagesDirectory; " BUILD.bazel" ])
536+
537+ let! bazelDefs = generateTopLevelBazelDefs context.SourceExplorer lock
538+
539+ do ! Files.writeFile ( Paths.combineAll [ " ." ; Constants.PackagesDirectory; Constants.BuckarooDefsFileName ]) bazelDefs
540+ }
541+
496542let task ( context : Tasks.TaskContext ) = async {
497543 let logger = createLogger context.Console None
498544
@@ -506,15 +552,11 @@ let task (context : Tasks.TaskContext) = async {
506552
507553 match context.BuildSystem with
508554 | Buck ->
509- do ! installBuckPackages context " ." [] lock.Packages
510555 do ! writeTopLevelBuckFiles context " ." lock
556+ do ! installBuckPackages context " ." [] lock.Packages
511557 | Bazel ->
512- do ! Files.mkdirp " buckaroo"
513- do ! Files.touch ( Paths.combine " buckaroo" " WORKSPACE" )
514- do ! Files.touch ( Paths.combine " buckaroo" " BUILD" )
558+ do ! writeTopLevelBazelFiles context lock
515559 do ! installBazelPackages context " ." [] lock.Packages
516- // failwith "Not implemented"
517- // TODO
518560
519561 logger.Success " The packages folder is now up-to-date. "
520562
0 commit comments