Merge pull request #171 from BendingBender/forbid-make-output-for-package

Forbid make output for package type projects
This commit is contained in:
Robin Heggelund Hansen 2023-01-10 10:46:09 +01:00 committed by GitHub
commit 577df0d8fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 148 additions and 57 deletions

1
.gitignore vendored
View File

@ -3,3 +3,4 @@ dist-newstyle
cabal-dev
.DS_Store
*~
.vscode

View File

@ -1869,6 +1869,8 @@ toGitErrorReport title err context =
data Make
= MakeNoOutline
| MakeCannotOptimizeAndDebug
| MakeCannotOutputForPackage
| MakeCannotOutputMainForPackage ModuleName.Raw [ModuleName.Raw]
| MakeBadDetails Details
| MakeAppNeedsFileNames
| MakePkgNeedsExposing
@ -1915,6 +1917,75 @@ makeToReport make =
\ add information to add the debugger. It is impossible to do both\
\ at once though! Pick just one of those flags and it should work!"
]
MakeCannotOutputForPackage ->
Help.docReport
"IMPOSSIBLE TO PRODUCE OUTPUT FOR A PACKAGE"
Nothing
( D.fillSep
[ "I",
"cannot",
"produce",
"output",
"requested",
"by",
"the",
D.dullyellow "--output",
"flag",
"for",
"a",
"project",
"of",
"type",
D.dullyellow "package."
]
)
[ D.reflow $
"If you only wanted to verify that your package builds correctly, try to remove the `--output` flag\
\ from your `gren make` command.",
D.reflow $
"Your project is defined as `\"type\": \"package\"` in your `gren.json`. This means that your project\
\ is meant to be used as a Gren package and cannot be compiled to any kind of output. Instead, it's \
\ meant to be consumed in its source form by another package or application. If you want to test your \
\ package with an application, simply create a separate project of type `application` and include this \
\ project in the \"source-directories\" property of the application's `gren.json`."
]
MakeCannotOutputMainForPackage m ms ->
Help.report
"IMPOSSIBLE TO PRODUCE OUTPUT FOR MAIN IN A PACKAGE"
Nothing
"I cannot produce output by compiling the given modules:"
[ D.indent 4 $ D.red $ D.vcat $ map D.fromName (m : ms),
D.fillSep
[ "They",
"contain",
"definitions",
"for",
D.dullyellow "main",
"functions,",
"which",
"would",
"normally",
"produce",
"html",
"output",
"but",
"your",
"project",
"is",
"of",
"type",
D.dullyellow "package."
],
D.reflow $
"If you only wanted to verify that your package builds correctly, try to remove the output paths to\
\ these modules from your `gren make` command or remove the main functions from the mentioned modules.",
D.reflow $
"Your project is defined as `\"type\": \"package\"` in your `gren.json`. This means that your project\
\ is meant to be used as a Gren package and cannot be compiled to any kind of output. Instead, it's \
\ meant to be consumed in its source form by another package or application. If you want to test your\
\ package with an application, simply create a separate project of type `application` and include this\
\ project in the \"source-directories\" property of the application's `gren.json`."
]
MakeBadDetails detailsProblem ->
toDetailsReport detailsProblem
MakeAppNeedsFileNames ->

View File

@ -24,6 +24,7 @@ import Generate.Node qualified as Node
import Gren.Details qualified as Details
import Gren.ModuleName qualified as ModuleName
import Gren.Platform qualified as Platform
import Parse.Module qualified as Parse
import Reporting qualified
import Reporting.Exit qualified as Exit
import Reporting.Task qualified as Task
@ -74,64 +75,74 @@ runHelp root paths style (Flags debug optimize maybeOutput _) =
desiredMode <- getMode debug optimize
details <- Task.eio Exit.MakeBadDetails (Details.load style scope root)
let platform = getPlatform details
case paths of
[] ->
do
exposed <- getExposed details
buildExposed style root details exposed
p : ps ->
do
artifacts <- buildPaths style root details (NE.List p ps)
case maybeOutput of
Nothing ->
case (platform, getMains artifacts) of
(_, []) ->
return ()
(Platform.Browser, [name]) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "index.html" (Html.sandwich name builder) (NE.List name [])
(Platform.Node, [name]) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "app" (Node.sandwich name builder) (NE.List name [])
(_, name : names) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "index.js" builder (NE.List name names)
Just DevStdOut ->
case getMains artifacts of
[] ->
return ()
let projectType = getProjectType details
case (projectType, maybeOutput) of
(Parse.Package _, Just _) ->
Task.throw Exit.MakeCannotOutputForPackage
_ ->
case paths of
[] ->
do
exposed <- getExposed details
buildExposed style root details exposed
p : ps ->
do
artifacts <- buildPaths style root details (NE.List p ps)
let mains = getMains artifacts
case (projectType, mains) of
(Parse.Package _, m : ms) ->
Task.throw $ Exit.MakeCannotOutputMainForPackage m ms
_ ->
do
builder <- toBuilder root details desiredMode artifacts
Task.io $ B.hPutBuilder IO.stdout builder
Just DevNull ->
return ()
Just (Exe target) ->
case platform of
Platform.Node -> do
name <- hasOneMain artifacts
builder <- toBuilder root details desiredMode artifacts
generate style target (Node.sandwich name builder) (NE.List name [])
_ -> do
Task.throw Exit.MakeExeOnlyForNodePlatform
Just (JS target) ->
case getNoMains artifacts of
[] -> do
builder <- toBuilder root details desiredMode artifacts
generate style target builder (Build.getRootNames artifacts)
name : names ->
Task.throw (Exit.MakeNonMainFilesIntoJavaScript name names)
Just (Html target) ->
case platform of
Platform.Browser -> do
name <- hasOneMain artifacts
builder <- toBuilder root details desiredMode artifacts
generate style target (Html.sandwich name builder) (NE.List name [])
_ -> do
Task.throw Exit.MakeHtmlOnlyForBrowserPlatform
case maybeOutput of
Nothing ->
case (platform, mains) of
(_, []) ->
return ()
(Platform.Browser, [name]) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "index.html" (Html.sandwich name builder) (NE.List name [])
(Platform.Node, [name]) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "app" (Node.sandwich name builder) (NE.List name [])
(_, name : names) ->
do
builder <- toBuilder root details desiredMode artifacts
generate style "index.js" builder (NE.List name names)
Just DevStdOut ->
case getMains artifacts of
[] ->
return ()
_ ->
do
builder <- toBuilder root details desiredMode artifacts
Task.io $ B.hPutBuilder IO.stdout builder
Just DevNull ->
return ()
Just (Exe target) ->
case platform of
Platform.Node -> do
name <- hasOneMain artifacts
builder <- toBuilder root details desiredMode artifacts
generate style target (Node.sandwich name builder) (NE.List name [])
_ -> do
Task.throw Exit.MakeExeOnlyForNodePlatform
Just (JS target) ->
case getNoMains artifacts of
[] -> do
builder <- toBuilder root details desiredMode artifacts
generate style target builder (Build.getRootNames artifacts)
name : names ->
Task.throw (Exit.MakeNonMainFilesIntoJavaScript name names)
Just (Html target) ->
case platform of
Platform.Browser -> do
name <- hasOneMain artifacts
builder <- toBuilder root details desiredMode artifacts
generate style target (Html.sandwich name builder) (NE.List name [])
_ -> do
Task.throw Exit.MakeHtmlOnlyForBrowserPlatform
-- GET INFORMATION
@ -168,6 +179,14 @@ getPlatform (Details.Details _ validOutline _ _ _ _) = do
Details.ValidPkg platform _ _ ->
platform
getProjectType :: Details.Details -> Parse.ProjectType
getProjectType (Details.Details _ validOutline _ _ _ _) = do
case validOutline of
Details.ValidApp _ _ ->
Parse.Application
Details.ValidPkg _ name _ ->
Parse.Package name
-- BUILD PROJECTS
buildExposed :: Reporting.Style -> FilePath -> Details.Details -> NE.List ModuleName.Raw -> Task ()