-
Notifications
You must be signed in to change notification settings - Fork 696
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
show-build-info (lib:Cabal part) #6108
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
11bede9
Add show-build-info command in lib:Cabal
bgamari 831a75e
Rebase and polish show-build-info implementation
fendor 9e1976e
Sync docs and implementation. [ci skip]
23Skidoo cff7a61
Formatting.
23Skidoo ac1fc0f
Small refactoring.
23Skidoo File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
-- | | ||
-- This module defines a simple JSON-based format for exporting basic | ||
-- information about a Cabal package and the compiler configuration Cabal | ||
-- would use to build it. This can be produced with the | ||
-- @cabal new-show-build-info@ command. | ||
-- | ||
-- | ||
-- This format is intended for consumption by external tooling and should | ||
-- therefore be rather stable. Moreover, this allows tooling users to avoid | ||
-- linking against Cabal. This is an important advantage as direct API usage | ||
-- tends to be rather fragile in the presence of user-initiated upgrades of | ||
-- Cabal. | ||
-- | ||
-- Below is an example of the output this module produces, | ||
-- | ||
-- @ | ||
-- { "cabal-version": "1.23.0.0", | ||
-- "compiler": { | ||
-- "flavour": "GHC", | ||
-- "compiler-id": "ghc-7.10.2", | ||
-- "path": "/usr/bin/ghc", | ||
-- }, | ||
-- "components": [ | ||
-- { "type": "lib", | ||
-- "name": "lib:Cabal", | ||
-- "compiler-args": | ||
-- ["-O", "-XHaskell98", "-Wall", | ||
-- "-package-id", "parallel-3.2.0.6-b79c38c5c25fff77f3ea7271851879eb"] | ||
-- "modules": ["Project.ModA", "Project.ModB", "Paths_project"], | ||
-- "src-files": [], | ||
-- "src-dirs": ["src"] | ||
-- } | ||
-- ] | ||
-- } | ||
-- @ | ||
-- | ||
-- The @cabal-version@ property provides the version of the Cabal library | ||
-- which generated the output. The @compiler@ property gives some basic | ||
-- information about the compiler Cabal would use to compile the package. | ||
-- | ||
-- The @components@ property gives a list of the Cabal 'Component's defined by | ||
-- the package. Each has, | ||
-- | ||
-- * @type@: the type of the component (one of @lib@, @exe@, | ||
-- @test@, @bench@, or @flib@) | ||
-- * @name@: a string serving to uniquely identify the component within the | ||
-- package. | ||
-- * @compiler-args@: the command-line arguments Cabal would pass to the | ||
-- compiler to compile the component | ||
-- * @modules@: the modules belonging to the component | ||
-- * @src-dirs@: a list of directories where the modules might be found | ||
-- * @src-files@: any other Haskell sources needed by the component | ||
-- | ||
-- Note: At the moment this is only supported when using the GHC compiler. | ||
-- | ||
|
||
module Distribution.Simple.ShowBuildInfo (mkBuildInfo) where | ||
|
||
import qualified Distribution.Simple.GHC as GHC | ||
import qualified Distribution.Simple.Program.GHC as GHC | ||
|
||
import Distribution.PackageDescription | ||
import Distribution.Compiler | ||
import Distribution.Verbosity | ||
import Distribution.Simple.Compiler | ||
import Distribution.Simple.LocalBuildInfo | ||
import Distribution.Simple.Program | ||
import Distribution.Simple.Setup | ||
import Distribution.Simple.Utils (cabalVersion) | ||
import Distribution.Simple.Utils.Json | ||
import Distribution.Types.TargetInfo | ||
import Distribution.Text | ||
import Distribution.Pretty | ||
|
||
-- | Construct a JSON document describing the build information for a | ||
-- package. | ||
mkBuildInfo | ||
:: PackageDescription -- ^ Mostly information from the .cabal file | ||
-> LocalBuildInfo -- ^ Configuration information | ||
-> BuildFlags -- ^ Flags that the user passed to build | ||
-> [TargetInfo] | ||
-> Json | ||
mkBuildInfo pkg_descr lbi _flags targetsToBuild = info | ||
where | ||
targetToNameAndLBI target = | ||
(componentLocalName $ targetCLBI target, targetCLBI target) | ||
componentsToBuild = map targetToNameAndLBI targetsToBuild | ||
(.=) :: String -> Json -> (String, Json) | ||
k .= v = (k, v) | ||
|
||
info = JsonObject | ||
[ "cabal-version" .= JsonString (display cabalVersion) | ||
, "compiler" .= mkCompilerInfo | ||
, "components" .= JsonArray (map mkComponentInfo componentsToBuild) | ||
] | ||
|
||
mkCompilerInfo = JsonObject | ||
[ "flavour" .= JsonString (prettyShow $ compilerFlavor $ compiler lbi) | ||
, "compiler-id" .= JsonString (showCompilerId $ compiler lbi) | ||
, "path" .= path | ||
] | ||
where | ||
path = maybe JsonNull (JsonString . programPath) | ||
$ (flavorToProgram . compilerFlavor $ compiler lbi) | ||
>>= flip lookupProgram (withPrograms lbi) | ||
|
||
flavorToProgram :: CompilerFlavor -> Maybe Program | ||
flavorToProgram GHC = Just ghcProgram | ||
flavorToProgram GHCJS = Just ghcjsProgram | ||
flavorToProgram UHC = Just uhcProgram | ||
flavorToProgram JHC = Just jhcProgram | ||
flavorToProgram _ = Nothing | ||
|
||
mkComponentInfo (name, clbi) = JsonObject | ||
[ "type" .= JsonString compType | ||
, "name" .= JsonString (prettyShow name) | ||
, "unit-id" .= JsonString (prettyShow $ componentUnitId clbi) | ||
, "compiler-args" .= JsonArray (map JsonString $ getCompilerArgs bi lbi clbi) | ||
, "modules" .= JsonArray (map (JsonString . display) modules) | ||
, "src-files" .= JsonArray (map JsonString sourceFiles) | ||
, "src-dirs" .= JsonArray (map JsonString $ hsSourceDirs bi) | ||
] | ||
where | ||
bi = componentBuildInfo comp | ||
Just comp = lookupComponent pkg_descr name | ||
compType = case comp of | ||
CLib _ -> "lib" | ||
CExe _ -> "exe" | ||
CTest _ -> "test" | ||
CBench _ -> "bench" | ||
CFLib _ -> "flib" | ||
modules = case comp of | ||
CLib lib -> explicitLibModules lib | ||
CExe exe -> exeModules exe | ||
_ -> [] | ||
sourceFiles = case comp of | ||
CLib _ -> [] | ||
CExe exe -> [modulePath exe] | ||
_ -> [] | ||
|
||
-- | Get the command-line arguments that would be passed | ||
-- to the compiler to build the given component. | ||
getCompilerArgs | ||
:: BuildInfo | ||
-> LocalBuildInfo | ||
-> ComponentLocalBuildInfo | ||
-> [String] | ||
getCompilerArgs bi lbi clbi = | ||
case compilerFlavor $ compiler lbi of | ||
GHC -> ghc | ||
GHCJS -> ghc | ||
c -> error $ "ShowBuildInfo.getCompilerArgs: Don't know how to get "++ | ||
"build arguments for compiler "++show c | ||
where | ||
-- This is absolutely awful | ||
ghc = GHC.renderGhcOptions (compiler lbi) (hostPlatform lbi) baseOpts | ||
where | ||
baseOpts = GHC.componentGhcOptions normal lbi bi clbi (buildDir lbi) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
-- | Utility json lib for Cabal | ||
-- TODO: Remove it again. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please explain. Make an issue, link to it. TODOs in the code are almost never fixed "immediately". |
||
module Distribution.Simple.Utils.Json | ||
( Json(..) | ||
, renderJson | ||
) where | ||
|
||
data Json = JsonArray [Json] | ||
| JsonBool !Bool | ||
| JsonNull | ||
| JsonNumber !Int | ||
| JsonObject [(String, Json)] | ||
| JsonString !String | ||
|
||
renderJson :: Json -> ShowS | ||
renderJson (JsonArray objs) = | ||
surround "[" "]" $ intercalate "," $ map renderJson objs | ||
renderJson (JsonBool True) = showString "true" | ||
renderJson (JsonBool False) = showString "false" | ||
renderJson JsonNull = showString "null" | ||
renderJson (JsonNumber n) = shows n | ||
renderJson (JsonObject attrs) = | ||
surround "{" "}" $ intercalate "," $ map render attrs | ||
where | ||
render (k,v) = (surround "\"" "\"" $ showString' k) . showString ":" . renderJson v | ||
renderJson (JsonString s) = surround "\"" "\"" $ showString' s | ||
|
||
surround :: String -> String -> ShowS -> ShowS | ||
surround begin end middle = showString begin . middle . showString end | ||
|
||
showString' :: String -> ShowS | ||
showString' xs = showStringWorker xs | ||
where | ||
showStringWorker :: String -> ShowS | ||
showStringWorker ('\"':as) = showString "\\\"" . showStringWorker as | ||
showStringWorker ('\\':as) = showString "\\\\" . showStringWorker as | ||
showStringWorker ('\'':as) = showString "\\\'" . showStringWorker as | ||
showStringWorker (x:as) = showString [x] . showStringWorker as | ||
showStringWorker [] = showString "" | ||
|
||
intercalate :: String -> [ShowS] -> ShowS | ||
intercalate sep = go | ||
where | ||
go [] = id | ||
go [x] = x | ||
go (x:xs) = x . showString' sep . go xs |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a ticket about this as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wish there was.