diff --git a/.gitignore b/.gitignore index 3a064370b..fdd090c65 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist-newstyle cabal-dev .DS_Store *~ +.vscode \ No newline at end of file diff --git a/builder/src/Reporting/Exit.hs b/builder/src/Reporting/Exit.hs index 67114ee04..a468a0f4f 100644 --- a/builder/src/Reporting/Exit.hs +++ b/builder/src/Reporting/Exit.hs @@ -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 -> diff --git a/terminal/src/Make.hs b/terminal/src/Make.hs index 38f94ed16..29c2c325e 100644 --- a/terminal/src/Make.hs +++ b/terminal/src/Make.hs @@ -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 ()