Skip to content

Commit

Permalink
Add package-local build tools to build-tool-depends
Browse files Browse the repository at this point in the history
(when `cabal-version >= 2`)
  • Loading branch information
sol committed Jan 24, 2025
1 parent 9444564 commit ff69985
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 11 deletions.
33 changes: 26 additions & 7 deletions src/Hpack/Render.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module Hpack.Render (
, Alignment(..)
, CommaStyle(..)
#ifdef TEST
, RenderEnv(..)
, renderConditional
, renderDependencies
, renderLibraryFields
Expand All @@ -48,7 +49,18 @@ import Hpack.Render.Hints
import Hpack.Render.Dsl hiding (sortFieldsBy)
import qualified Hpack.Render.Dsl as Dsl

type RenderM = Reader CabalVersion
data RenderEnv = RenderEnv {
renderEnvCabalVersion :: CabalVersion
, renderEnvPackageName :: String
}

type RenderM = Reader RenderEnv

getCabalVersion :: RenderM CabalVersion
getCabalVersion = asks renderEnvCabalVersion

getPackageName :: RenderM String
getPackageName = asks renderEnvPackageName

renderPackage :: [String] -> Package -> String
renderPackage oldCabalFile = renderPackageWith settings headerFieldsAlignment formattingHintsFieldOrder formattingHintsSectionsFieldOrder
Expand Down Expand Up @@ -82,7 +94,7 @@ renderPackageWith settings headerFieldsAlignment existingFieldOrder sectionsFiel
customSetup = maybe [] (return . renderCustomSetup) packageCustomSetup

stanzas :: [Element]
stanzas = flip runReader packageCabalVersion $ do
stanzas = flip runReader (RenderEnv packageCabalVersion packageName) $ do
library <- maybe (return []) (fmap return . renderLibrary) packageLibrary
internalLibraries <- renderInternalLibraries packageInternalLibraries
executables <- renderExecutables packageExecutables
Expand Down Expand Up @@ -357,21 +369,28 @@ renderBuildTools :: Map BuildTool DependencyVersion -> SystemBuildTools -> Rende
renderBuildTools buildTools systemBuildTools = do
xs <- traverse renderBuildTool $ Map.toList buildTools
return [
Field "build-tools" (CommaSeparatedList $ [x | BuildTools x <- xs] ++ renderSystemBuildTools systemBuildTools)
, Field "build-tool-depends" (CommaSeparatedList [x | BuildToolDepends x <- xs])
Field "build-tools" $ CommaSeparatedList $ [x | BuildTools x <- xs] ++ renderSystemBuildTools systemBuildTools
, Field "build-tool-depends" $ CommaSeparatedList [x | BuildToolDepends x <- xs]
]

data RenderBuildTool = BuildTools String | BuildToolDepends String

renderBuildTool :: (BuildTool, DependencyVersion) -> RenderM RenderBuildTool
renderBuildTool (buildTool, renderVersion -> version) = do
cabalVersion <- ask
cabalVersion <- getCabalVersion
packageName <- getPackageName
let supportsBuildTools = cabalVersion < makeCabalVersion [2]
return $ case buildTool of
LocalBuildTool executable -> BuildTools (executable ++ version)
LocalBuildTool executable
| supportsBuildTools -> BuildTools (executable ++ version)
| otherwise -> BuildToolDepends (packageName ++ ":" ++ executable ++ version)
BuildTool pkg executable
| cabalVersion < makeCabalVersion [2] && pkg == executable && executable `elem` knownBuildTools -> BuildTools (executable ++ version)
| supportsBuildTools && isknownBuildTool pkg executable -> BuildTools (executable ++ version)
| otherwise -> BuildToolDepends (pkg ++ ":" ++ executable ++ version)
where
isknownBuildTool :: String -> String -> Bool
isknownBuildTool pkg executable = pkg == executable && executable `elem` knownBuildTools

knownBuildTools :: [String]
knownBuildTools = [
"alex"
Expand Down
16 changes: 16 additions & 0 deletions test/EndToEndSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,22 @@ spec = around_ (inTempDirectoryNamed "my-package") $ do
bar ==0.2.0
|]

context "when cabal-version >= 2" $ do
it "adds it to build-tool-depends" $ do
[i|
verbatim:
cabal-version: 2.0
executables:
bar:
build-tools:
- bar
|] `shouldRenderTo` (executable_ "bar" [i|
autogen-modules:
Paths_my_package
build-tool-depends:
my-package:bar
|]) {packageCabalVersion = "2.0"}

context "when the name of a build tool matches a legacy system build tool" $ do
it "adds it to build-tools" $ do
[i|
Expand Down
10 changes: 6 additions & 4 deletions test/Hpack/RenderSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -225,17 +225,19 @@ spec = do
]

describe "renderConditional" $ do
let run = flip runReader (RenderEnv cabalVersion "foo")

it "renders conditionals" $ do
let conditional = Conditional "os(windows)" (section Empty) {sectionDependencies = deps ["Win32"]} Nothing
render defaultRenderSettings 0 (runReader (renderConditional renderEmptySection conditional) cabalVersion) `shouldBe` [
render defaultRenderSettings 0 (run $ renderConditional renderEmptySection conditional) `shouldBe` [
"if os(windows)"
, " build-depends:"
, " Win32"
]

it "renders conditionals with else-branch" $ do
let conditional = Conditional "os(windows)" (section Empty) {sectionDependencies = deps ["Win32"]} (Just $ (section Empty) {sectionDependencies = deps ["unix"]})
render defaultRenderSettings 0 (runReader (renderConditional renderEmptySection conditional) cabalVersion) `shouldBe` [
render defaultRenderSettings 0 (run $ renderConditional renderEmptySection conditional) `shouldBe` [
"if os(windows)"
, " build-depends:"
, " Win32"
Expand All @@ -247,7 +249,7 @@ spec = do
it "renders nested conditionals" $ do
let conditional = Conditional "arch(i386)" (section Empty) {sectionGhcOptions = ["-threaded"], sectionConditionals = [innerConditional]} Nothing
innerConditional = Conditional "os(windows)" (section Empty) {sectionDependencies = deps ["Win32"]} Nothing
render defaultRenderSettings 0 (runReader (renderConditional renderEmptySection conditional) cabalVersion) `shouldBe` [
render defaultRenderSettings 0 (run $ renderConditional renderEmptySection conditional) `shouldBe` [
"if arch(i386)"
, " ghc-options: -threaded"
, " if os(windows)"
Expand All @@ -258,7 +260,7 @@ spec = do
it "conditionalises both build-depends and mixins" $ do
let conditional = Conditional "os(windows)" (section Empty) {sectionDependencies = [("Win32", depInfo)]} Nothing
depInfo = defaultInfo { dependencyInfoMixins = ["hiding (Blah)"] }
render defaultRenderSettings 0 (runReader (renderConditional renderEmptySection conditional) cabalVersion) `shouldBe` [
render defaultRenderSettings 0 (run $ renderConditional renderEmptySection conditional) `shouldBe` [
"if os(windows)"
, " build-depends:"
, " Win32"
Expand Down

0 comments on commit ff69985

Please sign in to comment.