@@ -70,6 +70,7 @@ import Distribution.Client.ProjectConfig
70
70
, fetchAndReadSourcePackages
71
71
, projectConfigWithBuilderRepoContext
72
72
, resolveBuildTimeSettings
73
+ , withGlobalConfig
73
74
, withProjectOrGlobalConfig
74
75
)
75
76
import Distribution.Client.ProjectConfig.Types
@@ -344,153 +345,47 @@ installCommand =
344
345
-- For more details on how this works, see the module
345
346
-- "Distribution.Client.ProjectOrchestration"
346
347
installAction :: NixStyleFlags ClientInstallFlags -> [String ] -> GlobalFlags -> IO ()
347
- installAction flags@ NixStyleFlags {extraFlags = clientInstallFlags', .. } targetStrings globalFlags = do
348
+ installAction flags@ NixStyleFlags {extraFlags, configFlags, installFlags, projectFlags } targetStrings globalFlags = do
348
349
-- Ensure there were no invalid configuration options specified.
349
350
verifyPreconditionsOrDie verbosity configFlags'
350
351
351
352
-- We cannot use establishDummyProjectBaseContext to get these flags, since
352
353
-- it requires one of them as an argument. Normal establishProjectBaseContext
353
354
-- does not, and this is why this is done only for the install command
354
- clientInstallFlags <- getClientInstallFlags verbosity globalFlags clientInstallFlags'
355
-
355
+ clientInstallFlags <- getClientInstallFlags verbosity globalFlags extraFlags
356
+ -- FIXME: below commandLineFlagsToProjectConfig uses extraFlags
356
357
let
357
358
installLibs = fromFlagOrDefault False (cinstInstallLibs clientInstallFlags)
358
- targetFilter = if installLibs then Just LibKind else Just ExeKind
359
- targetStrings' = if null targetStrings then [" ." ] else targetStrings
360
-
361
- -- Note the logic here is rather goofy. Target selectors of the form "foo:bar" also parse as uris.
362
- -- However, we want install to also take uri arguments. Hence, we only parse uri arguments in the case where
363
- -- no project file is present (including an implicit one derived from being in a package directory)
364
- -- or where the --ignore-project flag is passed explicitly. In such a case we only parse colon-free target selectors
365
- -- as selectors, and otherwise parse things as URIs.
366
-
367
- -- However, in the special case where --ignore-project is passed with no selectors, we want to act as though this is
368
- -- a "normal" ignore project that actually builds and installs the selected package.
369
-
370
- withProject :: IO ([PackageSpecifier UnresolvedSourcePackage ], [URI ], [TargetSelector ], ProjectConfig )
371
- withProject = do
372
- let reducedVerbosity = lessVerbose verbosity
373
-
374
- -- First, we need to learn about what's available to be installed.
375
- localBaseCtx <-
376
- establishProjectBaseContext reducedVerbosity baseCliConfig InstallCommand
377
- let localDistDirLayout = distDirLayout localBaseCtx
378
- pkgDb <-
379
- projectConfigWithBuilderRepoContext
380
- reducedVerbosity
381
- (buildSettings localBaseCtx)
382
- (getSourcePackages verbosity)
383
-
384
- let
385
- (targetStrings'', packageIds) =
386
- partitionEithers
387
- . flip fmap targetStrings'
388
- $ \ str -> case simpleParsec str of
389
- Just (pkgId :: PackageId )
390
- | pkgVersion pkgId /= nullVersion -> Right pkgId
391
- _ -> Left str
392
- packageSpecifiers =
393
- flip fmap packageIds $ \ case
394
- PackageIdentifier {.. }
395
- | pkgVersion == nullVersion -> NamedPackage pkgName []
396
- | otherwise ->
397
- NamedPackage
398
- pkgName
399
- [ PackagePropertyVersion
400
- (thisVersion pkgVersion)
401
- ]
402
- packageTargets =
403
- flip TargetPackageNamed targetFilter . pkgName <$> packageIds
404
-
405
- if null targetStrings'' -- if every selector is already resolved as a packageid, return without further parsing.
406
- then return (packageSpecifiers, [] , packageTargets, projectConfig localBaseCtx)
407
- else do
408
- targetSelectors <-
409
- either (reportTargetSelectorProblems verbosity) return
410
- =<< readTargetSelectors
411
- (localPackages localBaseCtx)
412
- Nothing
413
- targetStrings''
414
-
415
- (specs, selectors) <-
416
- getSpecsAndTargetSelectors
417
- verbosity
418
- reducedVerbosity
419
- pkgDb
420
- targetSelectors
421
- localDistDirLayout
422
- localBaseCtx
423
- targetFilter
424
-
425
- return
426
- ( specs ++ packageSpecifiers
427
- , []
428
- , selectors ++ packageTargets
429
- , projectConfig localBaseCtx
430
- )
431
-
432
- withoutProject :: ProjectConfig -> IO ([PackageSpecifier UnresolvedSourcePackage ], [URI ], [TargetSelector ], ProjectConfig )
433
- withoutProject _ | null targetStrings = withProject -- if there's no targets, we don't parse specially, but treat it as install in a standard cabal package dir
434
- withoutProject globalConfig = do
435
- tss <- traverse (parseWithoutProjectTargetSelector verbosity) targetStrings'
436
- let
437
- projectConfig = globalConfig <> baseCliConfig
438
-
439
- ProjectConfigBuildOnly
440
- { projectConfigLogsDir
441
- } = projectConfigBuildOnly projectConfig
442
-
443
- ProjectConfigShared
444
- { projectConfigStoreDir
445
- } = projectConfigShared projectConfig
446
359
447
- mlogsDir = flagToMaybe projectConfigLogsDir
448
- mstoreDir = flagToMaybe projectConfigStoreDir
449
- cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
360
+ normalisedTargetStrings = if null targetStrings then [" ." ] else targetStrings
450
361
451
- let
452
- buildSettings =
453
- resolveBuildTimeSettings
454
- verbosity
455
- cabalDirLayout
456
- projectConfig
457
-
458
- SourcePackageDb {packageIndex} <-
459
- projectConfigWithBuilderRepoContext
460
- verbosity
461
- buildSettings
462
- (getSourcePackages verbosity)
463
-
464
- for_ (concatMap woPackageNames tss) $ \ name -> do
465
- when (null (lookupPackageName packageIndex name)) $ do
466
- let xs = searchByName packageIndex (unPackageName name)
467
- let emptyIf True _ = []
468
- emptyIf False zs = zs
469
- str2 =
470
- emptyIf
471
- (null xs)
472
- [ " Did you mean any of the following?\n "
473
- , unlines ((" - " ++ ) . unPackageName . fst <$> xs)
474
- ]
475
- dieWithException verbosity $ WithoutProject (unPackageName name) str2
476
-
477
- let
478
- (uris, packageSpecifiers) = partitionEithers $ map woPackageSpecifiers tss
479
- packageTargets = map woPackageTargets tss
480
-
481
- return (packageSpecifiers, uris, packageTargets, projectConfig)
362
+ -- Note the logic here is rather goofy. Target selectors of the form "foo:bar" also parse as uris.
363
+ -- However, we want install to also take uri arguments. Hence, we only parse uri arguments in the case where
364
+ -- no project file is present (including an implicit one derived from being in a package directory)
365
+ -- or where the --ignore-project flag is passed explicitly. In such a case we only parse colon-free target selectors
366
+ -- as selectors, and otherwise parse things as URIs.
482
367
483
- (specs, uris, targetSelectors, baseConfig) <-
484
- withProjectOrGlobalConfig verbosity ignoreProject globalConfigFlag withProject withoutProject
368
+ -- However, in the special case where --ignore-project is passed with no selectors, we want to act as though this is
369
+ -- a "normal" ignore project that actually builds and installs the selected package.
485
370
486
- -- We compute the base context again to determine packages available in the
487
- -- project to be installed, so we can list the available package names when
488
- -- the "all:..." variants of the target selectors are used.
489
- localPkgs <- localPackages <$> establishProjectBaseContext verbosity baseConfig InstallCommand
371
+ (specs, uris, targetSelectors, config) <-
372
+ let
373
+ with = do
374
+ (specs, targetSelectors, baseConfig) <-
375
+ withProject verbosity cliConfig normalisedTargetStrings installLibs
376
+ -- no URIs in this case
377
+ return (specs, [] , targetSelectors, baseConfig)
378
+
379
+ without =
380
+ withGlobalConfig verbosity globalConfigFlag $ \ globalConfig ->
381
+ withoutProject verbosity (globalConfig <> cliConfig) normalisedTargetStrings
382
+ in
383
+ -- if there's no targets, we don't parse specially, but treat it as install in a standard cabal package dir
384
+ if null targetStrings
385
+ then with
386
+ else withProjectOrGlobalConfig ignoreProject with without
490
387
491
388
let
492
- config = addLocalConfigToPkgs baseConfig (map pkgSpecifierTarget specs ++ concatMap (targetPkgNames localPkgs) targetSelectors)
493
-
494
389
ProjectConfig
495
390
{ projectConfigBuildOnly =
496
391
ProjectConfigBuildOnly
@@ -635,12 +530,13 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt
635
530
configFlags' = disableTestsBenchsByDefault configFlags
636
531
verbosity = fromFlagOrDefault normal (configVerbosity configFlags')
637
532
ignoreProject = flagIgnoreProject projectFlags
638
- baseCliConfig =
533
+ cliConfig =
639
534
commandLineFlagsToProjectConfig
640
535
globalFlags
641
536
flags{configFlags = configFlags'}
642
- clientInstallFlags'
643
- globalConfigFlag = projectConfigConfigFile (projectConfigShared baseCliConfig)
537
+ extraFlags
538
+
539
+ globalConfigFlag = projectConfigConfigFile (projectConfigShared cliConfig)
644
540
645
541
-- Do the install action for each executable in the install configuration.
646
542
traverseInstall :: InstallAction -> InstallCfg -> IO ()
@@ -649,7 +545,133 @@ installAction flags@NixStyleFlags{extraFlags = clientInstallFlags', ..} targetSt
649
545
actionOnExe <- action v overwritePolicy <$> prepareExeInstall cfg
650
546
traverse_ actionOnExe . Map. toList $ targetsMap buildCtx
651
547
652
- -- | Treat all direct targets of install command as local packages: #8637 and later #7297, #8909, #7236.
548
+ withProject
549
+ :: Verbosity
550
+ -> ProjectConfig
551
+ -> [String ]
552
+ -> Bool
553
+ -> IO ([PackageSpecifier UnresolvedSourcePackage ], [TargetSelector ], ProjectConfig )
554
+ withProject verbosity cliConfig targetStrings installLibs = do
555
+ -- First, we need to learn about what's available to be installed.
556
+ baseCtx <- establishProjectBaseContext reducedVerbosity cliConfig InstallCommand
557
+
558
+ (specs, selectors) <-
559
+ -- if every selector is already resolved as a packageid, return without further parsing.
560
+ if null unresolvedTargetStrings
561
+ then return (parsedSpecifiers, parsedTargets)
562
+ else do
563
+ (resolvedSpecifiers, resolvedTargets) <-
564
+ resolveTargetSelectorsInProjectBaseContext verbosity baseCtx targetStrings targetFilter
565
+ return (resolvedSpecifiers ++ parsedSpecifiers, resolvedTargets ++ parsedTargets)
566
+
567
+ -- Treat all direct targets of install command as local packages: #8637 and later #7297, #8909, #7236.
568
+ let config =
569
+ addLocalConfigToPkgs (projectConfig baseCtx) $
570
+ -- specifiers
571
+ map pkgSpecifierTarget specs
572
+ -- selectors
573
+ ++ concatMap (targetPkgNames $ localPackages baseCtx) selectors
574
+
575
+ return (specs, selectors, config)
576
+ where
577
+ reducedVerbosity = lessVerbose verbosity
578
+
579
+ (unresolvedTargetStrings, parsedPackageIds) =
580
+ partitionEithers $
581
+ flip map targetStrings $ \ s ->
582
+ case eitherParsec s of
583
+ Right pkgId@ PackageIdentifier {pkgVersion}
584
+ | pkgVersion /= nullVersion ->
585
+ pure pkgId
586
+ _ -> Left s
587
+
588
+ parsedSpecifiers :: [PackageSpecifier pkg ]
589
+ parsedSpecifiers = map specFromPkgId parsedPackageIds
590
+
591
+ parsedTargets :: [TargetSelector ]
592
+ parsedTargets =
593
+ [TargetPackageNamed (pkgName pkgId) targetFilter | pkgId <- parsedPackageIds]
594
+
595
+ targetFilter = if installLibs then Just LibKind else Just ExeKind
596
+
597
+ resolveTargetSelectorsInProjectBaseContext
598
+ :: Verbosity
599
+ -> ProjectBaseContext
600
+ -> [String ]
601
+ -> Maybe ComponentKindFilter
602
+ -> IO ([PackageSpecifier UnresolvedSourcePackage ], [TargetSelector ])
603
+ resolveTargetSelectorsInProjectBaseContext verbosity baseCtx targetStrings targetFilter = do
604
+ let reducedVerbosity = lessVerbose verbosity
605
+
606
+ pkgDb <-
607
+ projectConfigWithBuilderRepoContext
608
+ reducedVerbosity
609
+ (buildSettings baseCtx)
610
+ (getSourcePackages verbosity)
611
+
612
+ targetSelectors <-
613
+ readTargetSelectors (localPackages baseCtx) Nothing targetStrings
614
+ >>= \ case
615
+ Left problems -> reportTargetSelectorProblems verbosity problems
616
+ Right ts -> return ts
617
+
618
+ getSpecsAndTargetSelectors
619
+ verbosity
620
+ reducedVerbosity
621
+ pkgDb
622
+ targetSelectors
623
+ (distDirLayout baseCtx)
624
+ baseCtx
625
+ targetFilter
626
+
627
+ withoutProject
628
+ :: Verbosity
629
+ -> ProjectConfig
630
+ -> [String ]
631
+ -> IO ([PackageSpecifier UnresolvedSourcePackage ], [URI ], [TargetSelector ], ProjectConfig )
632
+ withoutProject verbosity globalConfig targetStrings = do
633
+ tss <- traverse (parseWithoutProjectTargetSelector verbosity) targetStrings
634
+ let
635
+ ProjectConfigBuildOnly
636
+ { projectConfigLogsDir
637
+ } = projectConfigBuildOnly globalConfig
638
+
639
+ ProjectConfigShared
640
+ { projectConfigStoreDir
641
+ } = projectConfigShared globalConfig
642
+
643
+ mlogsDir = flagToMaybe projectConfigLogsDir
644
+ mstoreDir = flagToMaybe projectConfigStoreDir
645
+
646
+ cabalDirLayout <- mkCabalDirLayout mstoreDir mlogsDir
647
+
648
+ let buildSettings = resolveBuildTimeSettings verbosity cabalDirLayout globalConfig
649
+
650
+ SourcePackageDb {packageIndex} <-
651
+ projectConfigWithBuilderRepoContext
652
+ verbosity
653
+ buildSettings
654
+ (getSourcePackages verbosity)
655
+
656
+ for_ (concatMap woPackageNames tss) $ \ name -> do
657
+ when (null (lookupPackageName packageIndex name)) $ do
658
+ let xs = searchByName packageIndex (unPackageName name)
659
+ let emptyIf True _ = []
660
+ emptyIf False zs = zs
661
+ str2 =
662
+ emptyIf
663
+ (null xs)
664
+ [ " Did you mean any of the following?\n "
665
+ , unlines ((" - " ++ ) . unPackageName . fst <$> xs)
666
+ ]
667
+ dieWithException verbosity $ WithoutProject (unPackageName name) str2
668
+
669
+ let
670
+ (uris, packageSpecifiers) = partitionEithers $ map woPackageSpecifiers tss
671
+ packageTargets = map woPackageTargets tss
672
+
673
+ return (packageSpecifiers, uris, packageTargets, globalConfig)
674
+
653
675
addLocalConfigToPkgs :: ProjectConfig -> [PackageName ] -> ProjectConfig
654
676
addLocalConfigToPkgs config pkgs =
655
677
config
@@ -707,8 +729,8 @@ getSpecsAndTargetSelectors
707
729
-> ProjectBaseContext
708
730
-> Maybe ComponentKindFilter
709
731
-> IO ([PackageSpecifier UnresolvedSourcePackage ], [TargetSelector ])
710
- getSpecsAndTargetSelectors verbosity reducedVerbosity pkgDb targetSelectors localDistDirLayout localBaseCtx targetFilter =
711
- withInstallPlan reducedVerbosity localBaseCtx $ \ elaboratedPlan _ -> do
732
+ getSpecsAndTargetSelectors verbosity reducedVerbosity pkgDb targetSelectors distDirLayout baseCtx targetFilter =
733
+ withInstallPlan reducedVerbosity baseCtx $ \ elaboratedPlan _ -> do
712
734
-- Split into known targets and hackage packages.
713
735
(targets, hackageNames) <-
714
736
partitionToKnownTargetsAndHackagePackages
@@ -724,11 +746,11 @@ getSpecsAndTargetSelectors verbosity reducedVerbosity pkgDb targetSelectors loca
724
746
sdistize (SpecificSourcePackage spkg) =
725
747
SpecificSourcePackage spkg'
726
748
where
727
- sdistPath = distSdistFile localDistDirLayout (packageId spkg)
749
+ sdistPath = distSdistFile distDirLayout (packageId spkg)
728
750
spkg' = spkg{srcpkgSource = LocalTarballPackage sdistPath}
729
751
sdistize named = named
730
752
731
- local = sdistize <$> localPackages localBaseCtx
753
+ local = sdistize <$> localPackages baseCtx
732
754
733
755
gatherTargets :: UnitId -> TargetSelector
734
756
gatherTargets targetId = TargetPackageNamed pkgName targetFilter
@@ -745,15 +767,15 @@ getSpecsAndTargetSelectors verbosity reducedVerbosity pkgDb targetSelectors loca
745
767
hackageTargets =
746
768
flip TargetPackageNamed targetFilter <$> hackageNames
747
769
748
- createDirectoryIfMissing True (distSdistDirectory localDistDirLayout )
770
+ createDirectoryIfMissing True (distSdistDirectory distDirLayout )
749
771
750
- unless (Map. null targets) $ for_ (localPackages localBaseCtx ) $ \ lpkg -> case lpkg of
772
+ unless (Map. null targets) $ for_ (localPackages baseCtx ) $ \ case
751
773
SpecificSourcePackage pkg ->
752
774
packageToSdist
753
775
verbosity
754
- (distProjectRootDirectory localDistDirLayout )
776
+ (distProjectRootDirectory distDirLayout )
755
777
TarGzArchive
756
- (distSdistFile localDistDirLayout (packageId pkg))
778
+ (distSdistFile distDirLayout (packageId pkg))
757
779
pkg
758
780
NamedPackage pkgName _ -> error $ " Got NamedPackage " ++ prettyShow pkgName
759
781
0 commit comments