on f4401ac help sign in
1765 lines 68 kB history raw
1{-# LANGUAGE OverloadedStrings #-}
2module Reporting.Exit
3 ( Init(..), initToReport
4 , Diff(..), diffToReport
5 , Make(..), makeToReport
6 , Bump(..), bumpToReport
7 , Repl(..), replToReport
8 , Publish(..), publishToReport
9 , Install(..), installToReport
10 , Reactor(..), reactorToReport
11 , newPackageOverview
12 --
13 , Solver(..)
14 , Outline(..)
15 , OutlineProblem(..)
16 , Details(..)
17 , PackageProblem(..)
18 , RegistryProblem(..)
19 , BuildProblem(..)
20 , BuildProjectProblem(..)
21 , DocsProblem(..)
22 , Generate(..)
23 --
24 , toString
25 , toStderr
26 , toJson
27 )
28 where
31import qualified Data.ByteString as BS
32import qualified Data.ByteString.Builder as B
33import qualified Data.ByteString.Char8 as BSC
34import qualified Data.ByteString.Lazy as LBS
35import qualified Data.ByteString.UTF8 as BS_UTF8
36import qualified Data.List as List
37import qualified Data.Name as N
38import qualified Data.NonEmptyList as NE
39import qualified Network.HTTP.Client as HTTP
40import qualified Network.HTTP.Types.Header as HTTP
41import qualified Network.HTTP.Types.Status as HTTP
43import qualified Elm.Constraint as C
44import qualified Elm.Magnitude as M
45import qualified Elm.ModuleName as ModuleName
46import qualified Elm.Package as Pkg
47import qualified Elm.Version as V
48import qualified File
49import qualified Http
50import qualified Json.Decode as Decode
51import qualified Json.Encode as Encode
52import qualified Json.String as Json
53import Parse.Primitives (Row, Col)
54import qualified Reporting.Annotation as A
55import Reporting.Doc ((<>))
56import qualified Reporting.Doc as D
57import qualified Reporting.Error.Import as Import
58import qualified Reporting.Error.Json as Json
59import qualified Reporting.Exit.Help as Help
60import qualified Reporting.Error as Error
61import qualified Reporting.Render.Code as Code
65-- RENDERERS
68toString :: Help.Report -> String
69toString report =
70 Help.toString (Help.reportToDoc report)
73toStderr :: Help.Report -> IO ()
74toStderr report =
75 Help.toStderr (Help.reportToDoc report)
78toJson :: Help.Report -> Encode.Value
79toJson report =
80 Help.reportToJson report
84-- INIT
87data Init
88 = InitNoSolution [Pkg.Name]
89 | InitNoOfflineSolution [Pkg.Name]
90 | InitSolverProblem Solver
91 | InitAlreadyExists
92 | InitRegistryProblem RegistryProblem
95initToReport :: Init -> Help.Report
96initToReport exit =
97 case exit of
98 InitNoSolution pkgs ->
99 Help.report "NO SOLUTION" Nothing
100 "I tried to create an elm.json with the following direct dependencies:"
101 [ D.indent 4 $ D.vcat $
102 map (D.dullyellow . D.fromChars . Pkg.toChars) pkgs
103 , D.reflow $
104 "I could not find compatible versions though! This should not happen, so please\
105 \ ask around one of the community forums at https://elm-lang.org/community to learn\
106 \ what is going on!"
107 ]
109 InitNoOfflineSolution pkgs ->
110 Help.report "NO OFFLINE SOLUTION" Nothing
111 "I tried to create an elm.json with the following direct dependencies:"
112 [ D.indent 4 $ D.vcat $
113 map (D.dullyellow . D.fromChars . Pkg.toChars) pkgs
114 , D.reflow $
115 "I could not find compatible versions though, but that may be because I could not\
116 \ connect to https://package.elm-lang.org to get the latest list of packages. Are\
117 \ you able to connect to the internet? Please ask around one of the community\
118 \ forums at https://elm-lang.org/community for help!"
119 ]
121 InitSolverProblem solver ->
122 error "TODO InitSolverProblem" solver
124 InitAlreadyExists ->
125 Help.report "EXISTING PROJECT" Nothing
126 "You already have an elm.json file, so there is nothing for me to initialize!"
127 [ D.fillSep
128 ["Maybe",D.green (D.fromChars (D.makeLink "init")),"can","help"
129 ,"you","figure","out","what","to","do","next?"
130 ]
131 ]
133 InitRegistryProblem problem ->
134 toRegistryProblemReport "PROBLEM LOADING PACKAGE LIST" problem $
135 "I need the list of published packages before I can start initializing projects"
139-- DIFF
142data Diff
143 = DiffNoOutline
144 | DiffBadOutline Outline
145 | DiffApplication
146 | DiffNoExposed
147 | DiffUnpublished
148 | DiffUnknownPackage Pkg.Name [Pkg.Name]
149 | DiffUnknownVersion Pkg.Name V.Version [V.Version]
150 | DiffDocsProblem V.Version DocsProblem
151 | DiffMustHaveLatestRegistry RegistryProblem
152 | DiffBadDetails Details
153 | DiffBadBuild BuildProblem
156diffToReport :: Diff -> Help.Report
157diffToReport diff =
158 case diff of
159 DiffNoOutline ->
160 Help.report "DIFF WHAT?" Nothing
161 "I cannot find an elm.json so I am not sure what you want me to diff.\
162 \ Normally you run `elm diff` from within a project!"
163 [ D.reflow $ "If you are just curious to see a diff, try running this command:"
164 , D.indent 4 $ D.green $ "elm diff elm/http 1.0.0 2.0.0"
165 ]
167 DiffBadOutline outline ->
168 toOutlineReport outline
170 DiffApplication ->
171 Help.report "CANNOT DIFF APPLICATIONS" (Just "elm.json")
172 "Your elm.json says this project is an application, but `elm diff` only works\
173 \ with packages. That way there are previously published versions of the API to\
174 \ diff against!"
175 [ D.reflow $ "If you are just curious to see a diff, try running this command:"
176 , D.indent 4 $ D.dullyellow $ "elm diff elm/http 1.0.0 2.0.0"
177 ]
179 DiffNoExposed ->
180 Help.report "NO EXPOSED MODULES" (Just "elm.json")
181 "Your elm.json has no \"exposed-modules\" which means there is no public API at\
182 \ all right now! What am I supposed to diff?"
183 [ D.reflow $
184 "Try adding some modules back to the \"exposed-modules\" field."
185 ]
187 DiffUnpublished ->
188 Help.report "UNPUBLISHED" Nothing
189 "This package is not published yet. There is nothing to diff against!"
190 []
192 DiffUnknownPackage pkg suggestions ->
193 Help.report "UNKNOWN PACKAGE" Nothing
194 ( "I cannot find a package called:"
195 )
196 [ D.indent 4 $ D.red $ D.fromChars $ Pkg.toChars pkg
197 , "Maybe you want one of these instead?"
198 , D.indent 4 $ D.dullyellow $ D.vcat $ map (D.fromChars . Pkg.toChars) suggestions
199 , "But check <https://package.elm-lang.org> to see all possibilities!"
200 ]
202 DiffUnknownVersion _pkg vsn realVersions ->
203 Help.docReport "UNKNOWN VERSION" Nothing
204 ( D.fillSep $
205 [ "Version", D.red (D.fromVersion vsn)
206 , "has", "never", "been", "published,", "so", "I"
207 , "cannot", "diff", "against", "it."
208 ]
209 )
210 [ "Here are all the versions that HAVE been published:"
211 , D.indent 4 $ D.dullyellow $ D.vcat $
212 let
213 sameMajor v1 v2 = V._major v1 == V._major v2
214 mkRow vsns = D.hsep $ map D.fromVersion vsns
215 in
216 map mkRow $ List.groupBy sameMajor (List.sort realVersions)
217 , "Want one of those instead?"
218 ]
220 DiffDocsProblem version problem ->
221 toDocsProblemReport problem $
222 "I need the docs for " ++ V.toChars version ++ " to compute this diff"
224 DiffMustHaveLatestRegistry problem ->
225 toRegistryProblemReport "PROBLEM UPDATING PACKAGE LIST" problem $
226 "I need the latest list of published packages before I do this diff"
228 DiffBadDetails details ->
229 toDetailsReport details
231 DiffBadBuild buildProblem ->
232 toBuildProblemReport buildProblem
236-- BUMP
239data Bump
240 = BumpNoOutline
241 | BumpBadOutline Outline
242 | BumpApplication
243 | BumpUnexpectedVersion V.Version [V.Version]
244 | BumpMustHaveLatestRegistry RegistryProblem
245 | BumpCannotFindDocs Pkg.Name V.Version DocsProblem
246 | BumpBadDetails Details
247 | BumpNoExposed
248 | BumpBadBuild BuildProblem
251bumpToReport :: Bump -> Help.Report
252bumpToReport bump =
253 case bump of
254 BumpNoOutline ->
255 Help.report "BUMP WHAT?" Nothing
256 "I cannot find an elm.json so I am not sure what you want me to bump."
257 [ D.reflow $
258 "Elm packages always have an elm.json that says current the version number. If\
259 \ you run this command from a directory with an elm.json file, I will try to bump\
260 \ the version in there based on the API changes."
261 ]
263 BumpBadOutline outline ->
264 toOutlineReport outline
266 BumpApplication ->
267 Help.report "CANNOT BUMP APPLICATIONS" (Just "elm.json")
268 "Your elm.json says this is an application. That means it cannot be published\
269 \ on <https://package.elm-lang.org> and therefore has no version to bump!"
270 []
272 BumpUnexpectedVersion vsn versions ->
273 Help.docReport "CANNOT BUMP" (Just "elm.json")
274 ( D.fillSep
275 ["Your","elm.json","says","I","should","bump","relative","to","version"
276 ,D.red (D.fromVersion vsn) <> ","
277 ,"but","I","cannot","find","that","version","on","<https://package.elm-lang.org>."
278 ,"That","means","there","is","no","API","for","me","to","diff","against","and"
279 ,"figure","out","if","these","are","MAJOR,","MINOR,","or","PATCH","changes."
280 ]
281 )
282 [ D.fillSep $
283 ["Try","bumping","again","after","changing","the",D.dullyellow "\"version\"","in","elm.json"]
284 ++ if length versions == 1 then ["to:"] else ["to","one","of","these:"]
285 , D.vcat $ map (D.green . D.fromVersion) versions
286 ]
288 BumpMustHaveLatestRegistry problem ->
289 toRegistryProblemReport "PROBLEM UPDATING PACKAGE LIST" problem $
290 "I need the latest list of published packages before I can bump any versions"
292 BumpCannotFindDocs _ version problem ->
293 toDocsProblemReport problem $
294 "I need the docs for " ++ V.toChars version ++ " to compute the next version number"
296 BumpBadDetails details ->
297 toDetailsReport details
299 BumpNoExposed ->
300 Help.docReport "NO EXPOSED MODULES" (Just "elm.json")
301 ( D.fillSep $
302 [ "To", "bump", "a", "package,", "the"
303 , D.dullyellow "\"exposed-modules\"", "field", "of", "your"
304 , "elm.json", "must", "list", "at", "least", "one", "module."
305 ]
306 )
307 [ D.reflow $
308 "Try adding some modules back to the \"exposed-modules\" field."
309 ]
311 BumpBadBuild problem ->
312 toBuildProblemReport problem
316-- OVERVIEW OF VERSIONING
319newPackageOverview :: String
320newPackageOverview =
321 unlines
322 [ "This package has never been published before. Here's how things work:"
323 , ""
324 , " - Versions all have exactly three parts: MAJOR.MINOR.PATCH"
325 , ""
326 , " - All packages start with initial version " ++ V.toChars V.one
327 , ""
328 , " - Versions are incremented based on how the API changes:"
329 , ""
330 , " PATCH = the API is the same, no risk of breaking code"
331 , " MINOR = values have been added, existing values are unchanged"
332 , " MAJOR = existing values have been changed or removed"
333 , ""
334 , " - I will bump versions for you, automatically enforcing these rules"
335 , ""
336 ]
340-- PUBLISH
343data Publish
344 = PublishNoOutline
345 | PublishBadOutline Outline
346 | PublishBadDetails Details
347 | PublishMustHaveLatestRegistry RegistryProblem
348 | PublishApplication
349 | PublishNotInitialVersion V.Version
350 | PublishAlreadyPublished V.Version
351 | PublishInvalidBump V.Version V.Version
352 | PublishBadBump V.Version V.Version M.Magnitude V.Version M.Magnitude
353 | PublishNoSummary
354 | PublishNoExposed
355 | PublishNoReadme
356 | PublishShortReadme
357 | PublishNoLicense
358 | PublishBuildProblem BuildProblem
359 | PublishMissingTag V.Version
360 | PublishCannotGetTag V.Version Http.Error
361 | PublishCannotGetTagData V.Version String BS.ByteString
362 | PublishCannotGetZip Http.Error
363 | PublishCannotDecodeZip String
364 | PublishCannotGetDocs V.Version V.Version DocsProblem
365 | PublishCannotRegister Http.Error
366 | PublishNoGit
367 | PublishLocalChanges V.Version
368 --
369 | PublishZipBadDetails Details
370 | PublishZipApplication
371 | PublishZipNoExposed
372 | PublishZipBuildProblem BuildProblem
375publishToReport :: Publish -> Help.Report
376publishToReport publish =
377 case publish of
378 PublishNoOutline ->
379 Help.report "PUBLISH WHAT?" Nothing
380 "I cannot find an elm.json so I am not sure what you want me to publish."
381 [ D.reflow $
382 "Elm packages always have an elm.json that states the version number,\
383 \ dependencies, exposed modules, etc."
384 ]
386 PublishBadOutline outline ->
387 toOutlineReport outline
389 PublishBadDetails problem ->
390 toDetailsReport problem
392 PublishMustHaveLatestRegistry problem ->
393 toRegistryProblemReport "PROBLEM UPDATING PACKAGE LIST" problem $
394 "I need the latest list of published packages to make sure this is safe to publish"
396 PublishApplication ->
397 Help.report "UNPUBLISHABLE" Nothing "I cannot publish applications, only packages!" []
399 PublishNotInitialVersion vsn ->
400 Help.docReport "INVALID VERSION" Nothing
401 ( D.fillSep
402 ["I","cannot","publish"
403 ,D.red (D.fromVersion vsn)
404 ,"as","the","initial","version."
405 ]
406 )
407 [ D.fillSep
408 ["Change","it","to",D.green "1.0.0","which","is"
409 ,"the","initial","version","for","all","Elm","packages."
410 ]
411 ]
413 PublishAlreadyPublished vsn ->
414 Help.docReport "ALREADY PUBLISHED" Nothing
415 ( D.vcat
416 [ D.fillSep
417 [ "Version", D.green (D.fromVersion vsn)
418 , "has", "already", "been", "published.", "You", "cannot"
419 , "publish", "it", "again!"
420 ]
421 , "Try using the `bump` command:"
422 ]
423 )
424 [ D.dullyellow $ D.indent 4 "elm bump"
425 , D.reflow $
426 "It computes the version number based on API changes, ensuring\
427 \ that no breaking changes end up in PATCH releases!"
428 ]
430 PublishInvalidBump statedVersion latestVersion ->
431 Help.docReport "INVALID VERSION" (Just "elm.json")
432 ( D.fillSep $
433 ["Your","elm.json","says","the","next","version","should","be"
434 ,D.red (D.fromVersion statedVersion) <> ","
435 ,"but","that","is","not","valid","based","on","the","previously"
436 ,"published","versions."
437 ]
438 )
439 [ D.fillSep $
440 ["Change","the","version","back","to"
441 ,D.green (D.fromVersion latestVersion)
442 ,"which","is","the","most","recently","published","version."
443 ,"From","there,","have","Elm","bump","the","version","by","running:"
444 ]
445 , D.indent 4 $ D.green "elm bump"
446 , D.reflow $
447 "If you want more insight on the API changes Elm detects, you\
448 \ can run `elm diff` at this point as well."
449 ]
451 PublishBadBump old new magnitude realNew realMagnitude ->
452 Help.docReport "INVALID VERSION" (Just "elm.json")
453 (
454 D.fillSep $
455 ["Your","elm.json","says","the","next","version","should","be"
456 ,D.red (D.fromVersion new) <> ","
457 ,"indicating","a",D.fromChars (M.toChars magnitude)
458 ,"change","to","the","public","API."
459 ,"This","does","not","match","the","API","diff","given","by:"
460 ]
461 )
462 [ D.indent 4 $ D.fromChars $
463 "elm diff " ++ V.toChars old
465 , D.fillSep $
466 ["This","command","says","this","is","a"
467 ,D.fromChars (M.toChars realMagnitude)
468 ,"change,","so","the","next","version","should","be"
469 ,D.green (D.fromVersion realNew) <> "."
470 ,"Double","check","everything","to","make","sure","you"
471 ,"are","publishing","what","you","want!"
472 ]
473 , D.reflow $
474 "Also, next time use `elm bump` and I'll figure all this out for you!"
475 ]
477 PublishNoSummary ->
478 Help.docReport "NO SUMMARY" (Just "elm.json")
479 ( D.fillSep $
480 [ "To", "publish", "a", "package,", "your", "elm.json", "must"
481 , "have", "a", D.dullyellow "\"summary\"", "field", "that", "gives"
482 , "a", "consice", "overview", "of", "your", "project."
483 ]
484 )
485 [ D.reflow $
486 "The summary must be less than 80 characters. It should describe\
487 \ the concrete use of your package as clearly and as plainly as possible."
488 ]
490 PublishNoExposed ->
491 Help.docReport "NO EXPOSED MODULES" (Just "elm.json")
492 ( D.fillSep $
493 [ "To", "publish", "a", "package,", "the"
494 , D.dullyellow "\"exposed-modules\"", "field", "of", "your"
495 , "elm.json", "must", "list", "at", "least", "one", "module."
496 ]
497 )
498 [ D.reflow $
499 "Which modules do you want users of the package to have access to? Add their\
500 \ names to the \"exposed-modules\" list."
501 ]
503 PublishNoReadme ->
504 toBadReadmeReport "NO README" $
505 "Every published package must have a helpful README.md\
506 \ file, but I do not see one in your project."
508 PublishShortReadme ->
509 toBadReadmeReport "SHORT README" $
510 "This README.md is too short. Having more details will help\
511 \ people assess your package quickly and fairly."
513 PublishNoLicense ->
514 Help.report "NO LICENSE FILE" (Just "LICENSE")
515 "By publishing a package you are inviting the Elm community to build\
516 \ upon your work. But without knowing your license, we have no idea if\
517 \ that is legal!"
518 [ D.reflow $
519 "Once you pick an OSI approved license from <https://spdx.org/licenses/>,\
520 \ you must share that choice in two places. First, the license\
521 \ identifier must appear in your elm.json file. Second, the full\
522 \ license text must appear in the root of your project in a file\
523 \ named LICENSE. Add that file and you will be all set!"
524 ]
526 PublishBuildProblem buildProblem ->
527 toBuildProblemReport buildProblem
529 PublishMissingTag version ->
530 let vsn = V.toChars version in
531 Help.docReport "NO TAG" Nothing
532 ( D.fillSep $
533 [ "Packages", "must", "be", "tagged", "in", "git,", "but", "I"
534 , "cannot", "find", "a", D.green (D.fromChars vsn), "tag."
535 ]
536 )
537 [ D.vcat
538 [ "These tags make it possible to find this specific version on GitHub."
539 , "To tag the most recent commit and push it to GitHub, run this:"
540 ]
541 , D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromChars $
542 [ "git tag -a " ++ vsn ++ " -m \"new release\""
543 , "git push origin " ++ vsn
544 ]
545 , "The -m flag is for a helpful message. Try to make it more informative!"
546 ]
548 PublishCannotGetTag version httpError ->
549 case httpError of
550 Http.BadHttp _ (HTTP.StatusCodeException response _)
551 | HTTP.statusCode (HTTP.responseStatus response) == 404 ->
552 let vsn = V.toChars version in
553 Help.report "NO TAG ON GITHUB" Nothing
554 ("You have version " ++ vsn ++ " tagged locally, but not on GitHub.")
555 [ D.reflow
556 "Run the following command to make this tag available on GitHub:"
557 , D.indent 4 $ D.dullyellow $ D.fromChars $
558 "git push origin " ++ vsn
559 , D.reflow
560 "This will make it possible to find your code online based on the version number."
561 ]
563 _ ->
564 toHttpErrorReport "PROBLEM VERIFYING TAG" httpError
565 "I need to check that the version tag is registered on GitHub"
567 PublishCannotGetTagData version url body ->
568 Help.report "PROBLEM VERIFYING TAG" Nothing
569 ("I need to check that version " ++ V.toChars version ++ " is tagged on GitHub, so I fetched:")
570 [ D.indent 4 $ D.dullyellow $ D.fromChars url
571 , D.reflow $
572 "I got the data back, but it was not what I was expecting. The response\
573 \ body contains " ++ show (BS.length body) ++ " bytes. Here is the "
574 ++ if BS.length body <= 76 then "whole thing:" else "beginning:"
575 , D.indent 4 $ D.dullyellow $ D.fromChars $
576 if BS.length body <= 76
577 then BS_UTF8.toString body
578 else take 73 (BS_UTF8.toString body) ++ "..."
579 , D.reflow $
580 "Does this error keep showing up? Maybe there is something weird with your\
581 \ internet connection. We have gotten reports that schools, businesses,\
582 \ airports, etc. sometimes intercept requests and add things to the body\
583 \ or change its contents entirely. Could that be the problem?"
584 ]
586 PublishCannotGetZip httpError ->
587 toHttpErrorReport "PROBLEM DOWNLOADING CODE" httpError $
588 "I need to check that folks can download and build the source code when they\
589 \ install this package"
591 PublishCannotDecodeZip url ->
592 Help.report "PROBLEM DOWNLOADING CODE" Nothing
593 "I need to check that folks can download and build the source code when they\
594 \ install this package, so I downloaded the code from:"
595 [ D.indent 4 $ D.dullyellow $ D.fromChars url
596 , D.reflow $
597 "I was unable to unzip the archive though. Maybe there is something weird with\
598 \ your internet connection. We have gotten reports that schools, businesses,\
599 \ airports, etc. sometimes intercept requests and add things to the body or\
600 \ change its contents entirely. Could that be the problem?"
601 ]
603 PublishCannotGetDocs old new docsProblem ->
604 toDocsProblemReport docsProblem $
605 "I need the docs for " ++ V.toChars old ++ " to verify that "
606 ++ V.toChars new ++ " really does come next"
608 PublishCannotRegister httpError ->
609 toHttpErrorReport "PROBLEM PUBLISHING PACKAGE" httpError $
610 "I need to send information about your package to the package website"
612 PublishNoGit ->
613 Help.report "NO GIT" Nothing
614 "I searched your PATH environment variable for `git` and could not\
615 \ find it. Is it available through your PATH?"
616 [ D.reflow $
617 "Who cares about this? Well, I currently use `git` to check if there\
618 \ are any local changes in your code. Local changes are a good sign\
619 \ that some important improvements have gotten mistagged, so this\
620 \ check can be extremely helpful for package authors!"
621 , D.toSimpleNote $
622 "We plan to do this without the `git` binary in a future release."
623 ]
625 PublishLocalChanges version ->
626 let vsn = V.toChars version in
627 Help.docReport "LOCAL CHANGES" Nothing
628 ( D.fillSep $
629 [ "The", "code", "tagged", "as", D.green (D.fromChars vsn), "in"
630 , "git", "does", "not", "match", "the", "code", "in", "your"
631 , "working", "directory.", "This", "means", "you", "have"
632 , "commits", "or", "local", "changes", "that", "are", "not"
633 , "going", "to", "be", "published!"
634 ]
635 )
636 [ D.toSimpleNote $
637 "If you are sure everything is in order, you can run `git checkout "
638 ++ vsn ++ "` and publish your code from there."
639 ]
641 PublishZipBadDetails _ ->
642 badZipReport
644 PublishZipApplication ->
645 badZipReport
647 PublishZipNoExposed ->
648 badZipReport
650 PublishZipBuildProblem _ ->
651 badZipReport
654toBadReadmeReport :: String -> String -> Help.Report
655toBadReadmeReport title summary =
656 Help.report title (Just "README.md") summary
657 [ D.reflow $
658 "When people look at your README, they are wondering:"
659 , D.vcat
660 [ " - What does this package even do?"
661 , " - Will it help me solve MY problems?"
662 ]
663 , D.reflow $
664 "So I recommend starting your README with a small example of the\
665 \ most common usage scenario. Show people what they can expect if\
666 \ they learn more!"
667 , D.toSimpleNote $
668 "By publishing your package, you are inviting people to invest time in\
669 \ understanding your work. Spending an hour on your README to communicate your\
670 \ knowledge more clearly can save the community days or weeks of time in\
671 \ aggregate, and saving time in aggregate is the whole point of publishing\
672 \ packages! People really appreciate it, and it makes the whole ecosystem feel\
673 \ nicer!"
674 ]
677badZipReport :: Help.Report
678badZipReport =
679 Help.report "PROBLEM VERIFYING PACKAGE" Nothing
680 "Before publishing packages, I download the code from GitHub and try to build it\
681 \ from scratch. That way I can be more confident that it will work for other\
682 \ people too. But I am not able to build it!"
683 [ D.reflow $
684 "I was just able to build your local copy though. Is there some way the version\
685 \ on GitHub could be different?"
686 ]
690-- DOCS
693data DocsProblem
694 = DP_Http Http.Error
695 | DP_Data String BS.ByteString
696 | DP_Cache
699toDocsProblemReport :: DocsProblem -> String -> Help.Report
700toDocsProblemReport problem context =
701 case problem of
702 DP_Http httpError ->
703 toHttpErrorReport "PROBLEM LOADING DOCS" httpError context
705 DP_Data url body ->
706 Help.report "PROBLEM LOADING DOCS" Nothing (context ++ ", so I fetched:")
707 [ D.indent 4 $ D.dullyellow $ D.fromChars url
708 , D.reflow $
709 "I got the data back, but it was not what I was expecting. The response\
710 \ body contains " ++ show (BS.length body) ++ " bytes. Here is the "
711 ++ if BS.length body <= 76 then "whole thing:" else "beginning:"
712 , D.indent 4 $ D.dullyellow $ D.fromChars $
713 if BS.length body <= 76
714 then BS_UTF8.toString body
715 else take 73 (BS_UTF8.toString body) ++ "..."
716 , D.reflow $
717 "Does this error keep showing up? Maybe there is something weird with your\
718 \ internet connection. We have gotten reports that schools, businesses,\
719 \ airports, etc. sometimes intercept requests and add things to the body\
720 \ or change its contents entirely. Could that be the problem?"
721 ]
723 DP_Cache ->
724 Help.report "PROBLEM LOADING DOCS" Nothing (context ++ ", but the local copy seems to be corrupted.")
725 [ D.reflow $
726 "I deleted the cached version, so the next run should download a fresh copy of\
727 \ the docs. Hopefully that will get you unstuck, but it will not resolve the root\
728 \ problem if, for example, a 3rd party editor plugin is modifing cached files\
729 \ for some reason."
730 ]
734-- INSTALL
737data Install
738 = InstallNoOutline
739 | InstallBadOutline Outline
740 | InstallBadRegistry RegistryProblem
741 | InstallNoArgs FilePath
742 | InstallNoOnlineSolution
743 | InstallNoOfflineSolution
744 | InstallHadSolverTrouble Solver
745 | InstallUnknownPackageOnline Pkg.Name [Pkg.Name]
746 | InstallUnknownPackageOffline Pkg.Name [Pkg.Name]
747 | InstallHasBadDetails Pkg.Name Encode.Value
750installToReport :: Install -> Help.Report
751installToReport exit =
752 case exit of
753 InstallNoOutline ->
754 Help.report "NEW PROJECT?" Nothing
755 "Are you trying to start a new project? Try this command instead:"
756 [ D.indent 4 $ D.green "elm init"
757 , D.reflow "It will help you get started!"
758 ]
760 InstallBadOutline outline ->
761 toOutlineReport outline
763 InstallBadRegistry problem ->
764 toRegistryProblemReport "PROBLEM LOADING PACKAGE LIST" problem $
765 "I need the list of published packages to figure out how to install things"
767 InstallNoArgs elmHome ->
768 Help.report "INSTALL WHAT?" Nothing
769 "I am expecting commands like:"
770 [ D.green $ D.indent 4 $ D.vcat $
771 [ "elm install elm/http"
772 , "elm install elm/json"
773 , "elm install elm/random"
774 ]
775 , D.toFancyHint
776 ["In","JavaScript","folks","run","`npm install`","to","start","projects."
777 ,"\"Gotta","download","everything!\"","But","why","download","packages"
778 ,"again","and","again?","Instead,","Elm","caches","packages","in"
779 ,D.dullyellow (D.fromChars elmHome)
780 ,"so","each","one","is","downloaded","and","built","ONCE","on","your","machine."
781 ,"Elm","projects","check","that","cache","before","trying","the","internet."
782 ,"This","reduces","build","times,","reduces","server","costs,","and","makes","it"
783 ,"easier","to","work","offline.","As","a","result"
784 ,D.dullcyan "elm install","is","only","for","adding","dependencies","to","elm.json,"
785 ,"whereas",D.dullcyan "elm make","is","in","charge","of","gathering","dependencies"
786 ,"and","building","everything.","So","maybe","try",D.green "elm make","instead?"
787 ]
788 ]
790 InstallNoOnlineSolution ->
791 Help.report "UNSOLVABLE DEPENDENCIES" (Just "elm.json") -- TODO recommend using solver in `elm reactor`
792 "This usually happens if you try to modify dependency constraints by\
793 \ hand. I recommend deleting any dependency you added recently (or all\
794 \ of them if things are bad) and then adding them again with:"
795 [ D.indent 4 $ D.green "elm install"
796 , D.reflow $
797 "And do not be afaid to ask for help on Slack if you get stuck!"
798 ]
800 InstallNoOfflineSolution ->
801 error "TODO InstallNoOfflineSolution"
803 InstallHadSolverTrouble solver ->
804 error "TODO InstallHadSolverTrouble" solver
806 InstallUnknownPackageOnline pkg suggestions ->
807 Help.docReport "UNKNOWN PACKAGE" Nothing
808 (
809 D.fillSep
810 ["I","cannot","find","a","package","named",D.red (D.fromPackage pkg) <> "."]
811 )
812 [ D.reflow $
813 "I looked through https://package.elm-lang.org for packages with similar names\
814 \ and found these:"
815 , D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromPackage suggestions
816 , D.reflow $ "Maybe you want one of these instead?"
817 ]
819 InstallUnknownPackageOffline pkg suggestions ->
820 Help.docReport "UNKNOWN PACKAGE" Nothing
821 (
822 D.fillSep
823 ["I","cannot","find","a","package","named",D.red (D.fromPackage pkg) <> "."]
824 )
825 [ D.reflow $
826 "I could not connect to https://package.elm-lang.org though, so new packages may\
827 \ have been published since I last updated my local cache of package names."
828 , D.reflow $
829 "Looking through the locally cached names, the closest ones are:"
830 , D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromPackage suggestions
831 , D.reflow $ "Maybe you want one of these instead?"
832 ]
834 InstallHasBadDetails pkg outline ->
835 Help.report "INSTALL PROBLEM" Nothing
836 (
837 "I found a version of " ++ Pkg.toChars pkg ++ " that claims to be compatible with\
838 \ your existing dependencies, but I ran into an error when I tried to build it locally."
839 )
840 [ D.reflow $
841 "Here is an elm.json that should reproduce the error with a bit more information:"
842 , D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromChars $
843 map BS_UTF8.toString $ BSC.lines $ LBS.toStrict $ B.toLazyByteString $
844 Encode.encode outline
845 , D.reflow $
846 "Maybe that can help figure out what is going on here."
847 ]
850{- TODO detect if library has no 0.19.0 version. Maybe do this on website though?
851 Help.report "OLD DEPENDENCIES" (Just "elm.json")
852 ( "The following packages do not work with Elm " ++ V.toChars V.compiler ++ " right now:"
853 )
854 [ D.indent 4 $ D.vcat $ map (D.red . D.fromPackage) badPackages
855 , D.reflow $
856 "This may be because it is not upgraded yet. It may be because a\
857 \ better solution came along, so there was no need to upgrade it.\
858 \ Etc. Try asking around on Slack to learn more about the topic."
859 , D.toSimpleNote
860 "Whatever the case, please be kind to the relevant package authors! Having\
861 \ friendly interactions with users is great motivation, and conversely, getting\
862 \ berated by strangers on the internet sucks your soul dry. Furthermore, package\
863 \ authors are humans with families, friends, jobs, vacations, responsibilities,\
864 \ goals, etc. They face obstacles outside of their technical work you will never\
865 \ know about, so please assume the best and try to be patient and supportive!"
866 ]
867-}
871-- SOLVER
874data Solver
875 = SolverBadCacheData Pkg.Name V.Version
876 | SolverBadHttpData Pkg.Name V.Version
877 | SolverBadHttp Http.Error
881-- OUTLINE
884data Outline
885 = OutlineHasBadStructure (Decode.Error OutlineProblem)
886 | OutlineHasBadSrcDirs FilePath [FilePath]
887 | OutlineNoPkgCore
888 | OutlineNoAppCore
889 | OutlineNoAppJson
892data OutlineProblem
893 = OP_BadType
894 | OP_BadPkgName Row Col
895 | OP_BadVersion Row Col
896 | OP_BadConstraint C.Error
897 | OP_BadModuleName Row Col
898 | OP_BadModuleHeaderTooLong
899 | OP_BadDependencyName Row Col
900 | OP_BadLicense Json.String [Json.String]
901 | OP_BadSummaryTooLong
902 | OP_NoSrcDirs
905toOutlineReport :: Outline -> Help.Report
906toOutlineReport problem =
907 case problem of
908 OutlineHasBadStructure decodeError ->
909 Json.toReport "elm.json" (Json.FailureToReport toOutlineProblemReport) decodeError $
910 Json.ExplicitReason "I ran into a problem with your elm.json file."
912 OutlineHasBadSrcDirs dir dirs ->
913 case dirs of
914 [] ->
915 Help.report "MISSING SOURCE DIRECTORY" (Just "elm.json")
916 "I need a valid elm.json file, but the \"source-directories\" field lists the following directory:"
917 [ D.indent 4 $ D.dullyellow $ D.fromChars dir
918 , D.reflow $
919 "I cannot find it though. Is it missing? Is there a typo?"
920 ]
922 _:_ ->
923 Help.report "MISSING SOURCE DIRECTORIES" (Just "elm.json")
924 "I need a valid elm.json file, but the \"source-directories\" field lists the following directories:"
925 [ D.indent 4 $ D.dullyellow $ D.fromChars dir
926 , D.reflow $
927 "I cannot find them though. Are they missing? Are there typos?"
928 ]
930 OutlineNoPkgCore ->
931 Help.report "MISSING DEPENDENCY" (Just "elm.json")
932 "I need a valid elm.json file, so I need to see an \"elm/core\" dependency in there. Try running:"
933 [ D.indent 4 $ D.green $ "elm install elm/core"
934 , D.reflow "I need it for the default imports that make `List` and `Maybe` available."
935 ]
937 OutlineNoAppCore ->
938 Help.report "MISSING DEPENDENCY" (Just "elm.json")
939 "I need a valid elm.json file, so I need to see an \"elm/core\" dependency in there. Try running:"
940 [ D.indent 4 $ D.green $ "elm install elm/core"
941 , D.reflow "It has some supporting code that is needed by every Elm application!"
942 ]
944 OutlineNoAppJson ->
945 Help.report "MISSING DEPENDENCY" (Just "elm.json")
946 "I need a valid elm.json file, so I need to see an \"elm/json\" dependency in there. Try running:"
947 [ D.indent 4 $ D.green $ "elm install elm/json"
948 , D.reflow "It helps me handle flags and ports."
949 ]
952toOutlineProblemReport :: FilePath -> Code.Source -> Json.Context -> A.Region -> OutlineProblem -> Help.Report
953toOutlineProblemReport path source _ region problem =
954 let
955 toHighlight row col =
956 Just $ A.Region (A.Position row col) (A.Position row col)
958 toSnippet title highlight pair =
959 Help.jsonReport title (Just path) $
960 Code.toSnippet source region highlight pair
961 in
962 case problem of
963 OP_BadType ->
964 toSnippet "UNEXPECTED TYPE" Nothing
965 ( D.reflow $
966 "I got stuck while reading your elm.json file. I cannot handle a \"type\" like this:"
967 , D.fillSep
968 ["Try","changing","the","\"type\"","to"
969 ,D.green "\"application\"","or",D.green "\"package\"","instead."
970 ]
971 )
973 OP_BadPkgName row col ->
974 toSnippet "INVALID PACKAGE NAME" (toHighlight row col)
975 ( D.reflow $
976 "I got stuck while reading your elm.json file. I ran into trouble with the package name:"
977 , D.stack
978 [ D.fillSep
979 ["Package","names","are","always","written","as"
980 ,D.green "\"author/project\""
981 ,"so","I","am","expecting","to","see","something","like:"
982 ]
983 , D.dullyellow $ D.indent 4 $ D.vcat $
984 [ "\"mdgriffith/elm-ui\""
985 , "\"w0rm/elm-physics\""
986 , "\"Microsoft/elm-json-tree-view\""
987 , "\"FordLabs/elm-star-rating\""
988 , "\"1602/json-schema\""
989 ]
990 , D.reflow
991 "The author name should match your GitHub name exactly, and the project name\
992 \ needs to follow these rules:"
993 , D.indent 4 $ D.vcat $
994 [ "+--------------------------------------+-----------+-----------+"
995 , "| RULE | BAD | GOOD |"
996 , "+--------------------------------------+-----------+-----------+"
997 , "| only lower case, digits, and hyphens | elm-HTTP | elm-http |"
998 , "| no leading digits | 3D | elm-3d |"
999 , "| no non-ASCII characters | elm-bjørn | elm-bear |"
1000 , "| no underscores | elm_ui | elm-ui |"
1001 , "| no double hyphens | elm--hash | elm-hash |"
1002 , "| no starting or ending hyphen | -elm-tar- | elm-tar |"
1003 , "+--------------------------------------+-----------+-----------+"
1005 , D.toSimpleNote $
1006 "These rules only apply to the project name, so you should never need\
1007 \ to change your GitHub name!"
1011 OP_BadVersion row col ->
1012 toSnippet "PROBLEM WITH VERSION" (toHighlight row col)
1013 ( D.reflow $
1014 "I got stuck while reading your elm.json file. I was expecting a version number here:"
1015 , D.fillSep
1016 ["I","need","something","like",D.green "\"1.0.0\"","or",D.green "\"2.0.4\""
1017 ,"that","explicitly","states","all","three","numbers!"
1021 OP_BadConstraint constraintError ->
1022 case constraintError of
1023 C.BadFormat row col ->
1024 toSnippet "PROBLEM WITH CONSTRAINT" (toHighlight row col)
1025 ( D.reflow $
1026 "I got stuck while reading your elm.json file. I do not understand this version constraint:"
1027 , D.stack
1028 [ D.fillSep
1029 ["I","need","something","like",D.green "\"1.0.0 <= v < 2.0.0\""
1030 ,"that","explicitly","lists","the","lower","and","upper","bounds."
1032 , D.toSimpleNote $
1033 "The spaces in there are required! Taking them out will confuse me. Adding\
1034 \ extra spaces confuses me too. I recommend starting with a valid example\
1035 \ and just changing the version numbers."
1039 C.InvalidRange before after ->
1040 if before == after then
1041 toSnippet "PROBLEM WITH CONSTRAINT" Nothing
1042 ( D.reflow $
1043 "I got stuck while reading your elm.json file. I ran into an invalid version constraint:"
1044 , D.fillSep
1045 ["Elm","checks","that","all","package","APIs","follow","semantic","versioning,"
1046 ,"so","it","is","best","to","use","wide","constraints.","I","recommend"
1047 ,D.green $ "\"" <> D.fromVersion before <> " <= v < " <> D.fromVersion (V.bumpMajor after) <> "\""
1048 ,"since","it","is","guaranteed","that","breaking","API","changes","cannot"
1049 ,"happen","in","any","of","the","versions","in","that","range."
1053 else
1054 toSnippet "PROBLEM WITH CONSTRAINT" Nothing
1055 ( D.reflow $
1056 "I got stuck while reading your elm.json file. I ran into an invalid version constraint:"
1057 , D.fillSep
1058 ["Maybe","you","want","something","like"
1059 ,D.green $ "\"" <> D.fromVersion before <> " <= v < " <> D.fromVersion (V.bumpMajor before) <> "\""
1060 ,"instead?","Elm","checks","that","all","package","APIs","follow","semantic"
1061 ,"versioning,","so","it","is","guaranteed","that","breaking","API","changes"
1062 ,"cannot","happen","in","any","of","the","versions","in","that","range."
1066 OP_BadModuleName row col ->
1067 toSnippet "PROBLEM WITH MODULE NAME" (toHighlight row col)
1068 ( D.reflow $
1069 "I got stuck while reading your elm.json file. I was expecting a module name here:"
1070 , D.fillSep
1071 ["I","need","something","like",D.green "\"Html.Events\""
1072 ,"or",D.green "\"Browser.Navigation\""
1073 ,"where","each","segment","starts","with","a","capital"
1074 ,"letter","and","the","segments","are","separated","by","dots."
1078 OP_BadModuleHeaderTooLong ->
1079 toSnippet "HEADER TOO LONG" Nothing
1080 ( D.reflow $
1081 "I got stuck while reading your elm.json file. This section header is too long:"
1082 , D.fillSep
1083 ["I","need","it","to","be"
1084 ,D.green "under",D.green "20",D.green "characters"
1085 ,"so","it","renders","nicely","on","the","package","website!"
1089 OP_BadDependencyName row col ->
1090 toSnippet "PROBLEM WITH DEPENDENCY NAME" (toHighlight row col)
1091 ( D.reflow $
1092 "I got stuck while reading your elm.json file. There is something wrong with this dependency name:"
1093 , D.stack
1094 [ D.fillSep
1095 ["Package","names","always","include","the","name","of","the","author,"
1096 ,"so","I","am","expecting","to","see","dependencies","like"
1097 ,D.dullyellow "\"mdgriffith/elm-ui\"","and"
1098 ,D.dullyellow "\"Microsoft/elm-json-tree-view\"" <> "."
1100 , D.fillSep $
1101 ["I","generally","recommend","finding","the","package","you","want","on"
1102 ,"the","package","website,","and","installing","it","with","the"
1103 ,D.green "elm install","command!"
1108 OP_BadLicense _ suggestions ->
1109 toSnippet "UNKNOWN LICENSE" Nothing
1110 ( D.reflow $
1111 "I got stuck while reading your elm.json file. I do not know about this type of license:"
1113 D.stack
1114 [ D.fillSep
1115 ["Elm","packages","generally","use"
1116 ,D.green "\"BSD-3-Clause\"","or",D.green "\"MIT\"" <> ","
1117 ,"but","I","accept","any","OSI","approved","SPDX","license."
1118 ,"Here","some","that","seem","close","to","what","you","wrote:"
1120 , D.indent 4 $ D.dullyellow $ D.vcat $ map (D.fromChars . Json.toChars) suggestions
1121 , D.reflow $
1122 "Check out https://spdx.org/licenses/ for the full list of options."
1126 OP_BadSummaryTooLong ->
1127 toSnippet "SUMMARY TOO LONG" Nothing
1128 ( D.reflow $
1129 "I got stuck while reading your elm.json file. Your \"summary\" is too long:"
1130 , D.fillSep
1131 ["I","need","it","to","be"
1132 ,D.green "under",D.green "80",D.green "characters"
1133 ,"so","it","renders","nicely","on","the","package","website!"
1137 OP_NoSrcDirs ->
1138 toSnippet "NO SOURCE DIRECTORIES" Nothing
1139 ( D.reflow $
1140 "I got stuck while reading your elm.json file. You do not have any \"source-directories\" listed here:"
1141 , D.fillSep
1142 ["I","need","something","like",D.green "[\"src\"]"
1143 ,"so","I","know","where","to","look","for","your","modules!"
1149-- DETAILS
1152data Details
1153 = DetailsNoSolution
1154 | DetailsNoOfflineSolution
1155 | DetailsSolverProblem Solver
1156 | DetailsBadElmInPkg C.Constraint
1157 | DetailsBadElmInAppOutline V.Version
1158 | DetailsHandEditedDependencies
1159 | DetailsBadOutline Outline
1160 | DetailsCannotGetRegistry RegistryProblem
1161 | DetailsCannotBuildPackage Pkg.Name V.Version PackageProblem
1164toDetailsReport :: Details -> Help.Report
1165toDetailsReport details =
1166 case details of
1167 DetailsNoSolution ->
1168 Help.report "INCOMPATIBLE DEPENDENCIES" (Just "elm.json")
1169 "The dependencies in your elm.json are not compatible."
1170 [ D.fillSep
1171 ["Did","you","change","them","by","hand?","Try","to","change","it","back!"
1172 ,"It","is","much","more","reliable","to","add","dependencies","with",D.green "elm install"
1173 ,"or","the","dependency","management","tool","in",D.green "elm reactor" <> "."
1175 , D.reflow $
1176 "Please ask for help on the community forums if you try those paths and are still\
1177 \ having problems!"
1180 DetailsNoOfflineSolution ->
1181 Help.report "TROUBLE VERIFYING DEPENDENCIES" (Just "elm.json")
1182 "I could not connect to https://package.elm-lang.org to get the latest list of\
1183 \ packages, and I was unable to verify your dependencies with the information I\
1184 \ have cached locally."
1185 [ D.reflow $
1186 "Are you able to connect to the internet? These dependencies may work once you\
1187 \ get access to the registry!"
1188 , D.toFancyNote
1189 ["If","you","changed","your","dependencies","by","hand,","try","to","change","them","back!"
1190 ,"It","is","much","more","reliable","to","add","dependencies","with",D.green "elm install"
1191 ,"or","the","dependency","management","tool","in",D.green "elm reactor" <> "."
1195 DetailsSolverProblem _ ->
1196 error "TODO DetailsSolverProblem"
1198 DetailsBadElmInPkg constraint ->
1199 Help.report "ELM VERSION MISMATCH" (Just "elm.json")
1200 "Your elm.json says this package needs a version of Elm in this range:"
1201 [ D.indent 4 $ D.dullyellow $ D.fromChars $ C.toChars constraint
1202 , D.fillSep
1203 [ "But", "you", "are", "using", "Elm"
1204 , D.red (D.fromVersion V.compiler)
1205 , "right", "now."
1209 DetailsBadElmInAppOutline version ->
1210 Help.report "ELM VERSION MISMATCH" (Just "elm.json")
1211 "Your elm.json says this application needs a different version of Elm."
1212 [ D.fillSep
1213 [ "It", "requires"
1214 , D.green (D.fromVersion version) <> ","
1215 , "but", "you", "are", "using"
1216 , D.red (D.fromVersion V.compiler)
1217 , "right", "now."
1221 DetailsHandEditedDependencies ->
1222 Help.report "ERROR IN DEPENDENCIES" (Just "elm.json")
1223 "It looks like the dependencies elm.json in were edited by hand (or by a 3rd\
1224 \ party tool) leaving them in an invalid state."
1225 [ D.fillSep
1226 ["Try","to","change","them","back","to","what","they","were","before!"
1227 ,"It","is","much","more","reliable","to","add","dependencies","with",D.green "elm install"
1228 ,"or","the","dependency","management","tool","in",D.green "elm reactor" <> "."
1230 , D.reflow $
1231 "Please ask for help on the community forums if you try those paths and are still\
1232 \ having problems!"
1235 DetailsBadOutline outline ->
1236 toOutlineReport outline
1238 DetailsCannotGetRegistry problem ->
1239 toRegistryProblemReport "PROBLEM LOADING PACKAGE LIST" problem $
1240 "I need the list of published packages to verify your dependencies"
1242 DetailsCannotBuildPackage pkg vsn problem ->
1243 toPackageProblemReport pkg vsn problem
1247-- PACKAGE PROBLEM
1250data PackageProblem
1251 = PP_BadEndpointRequest Http.Error
1252 | PP_BadEndpointContent String
1253 | PP_BadArchiveRequest Http.Error
1254 | PP_BadArchiveContent String
1255 | PP_BadArchiveHash String String String
1258toPackageProblemReport :: Pkg.Name -> V.Version -> PackageProblem -> Help.Report
1259toPackageProblemReport pkg vsn problem =
1260 let
1261 thePackage =
1262 Pkg.toChars pkg ++ " " ++ V.toChars vsn
1263 in
1264 case problem of
1265 PP_BadEndpointRequest httpError ->
1266 toHttpErrorReport "PROBLEM DOWNLOADING PACKAGE" httpError $
1267 "I need to find the latest download link for " ++ thePackage
1269 PP_BadEndpointContent url ->
1270 Help.report "PROBLEM DOWNLOADING PACKAGE" Nothing
1272 "I need to find the latest download link for " ++ thePackage ++ ", but I ran into corrupted information from:"
1274 [ D.indent 4 $ D.dullyellow $ D.fromChars url
1275 , D.reflow $
1276 "Is something weird with your internet connection. We have gotten reports that\
1277 \ schools, businesses, airports, etc. sometimes intercept requests and add things\
1278 \ to the body or change its contents entirely. Could that be the problem?"
1281 PP_BadArchiveRequest httpError ->
1282 toHttpErrorReport "PROBLEM DOWNLOADING PACKAGE" httpError $
1283 "I was trying to download the source code for " ++ thePackage
1285 PP_BadArchiveContent url ->
1286 Help.report "PROBLEM DOWNLOADING PACKAGE" Nothing
1288 "I downloaded the source code for " ++ thePackage ++ " from:"
1290 [ D.indent 4 $ D.dullyellow $ D.fromChars url
1291 , D.reflow $
1292 "But I was unable to unzip the data. Maybe there is something weird with\
1293 \ your internet connection. We have gotten reports that schools, businesses,\
1294 \ airports, etc. sometimes intercept requests and add things to the body or\
1295 \ change its contents entirely. Could that be the problem?"
1298 PP_BadArchiveHash url expectedHash actualHash ->
1299 Help.report "CORRUPT PACKAGE DATA" Nothing
1301 "I downloaded the source code for " ++ thePackage ++ " from:"
1303 [ D.indent 4 $ D.dullyellow $ D.fromChars url
1304 , D.reflow "But it looks like the hash of the archive has changed since publication:"
1305 , D.vcat $ map D.fromChars $
1306 [ " Expected: " ++ expectedHash
1307 , " Actual: " ++ actualHash
1309 , D.reflow $
1310 "This usually means that the package author moved the version\
1311 \ tag, so report it to them and see if that is the issue. Folks\
1312 \ on Elm slack can probably help as well."
1317-- REGISTRY PROBLEM
1320data RegistryProblem
1321 = RP_Http Http.Error
1322 | RP_Data String BS.ByteString
1325toRegistryProblemReport :: String -> RegistryProblem -> String -> Help.Report
1326toRegistryProblemReport title problem context =
1327 case problem of
1328 RP_Http err ->
1329 toHttpErrorReport title err context
1331 RP_Data url body ->
1332 Help.report title Nothing (context ++ ", so I fetched:")
1333 [ D.indent 4 $ D.dullyellow $ D.fromChars url
1334 , D.reflow $
1335 "I got the data back, but it was not what I was expecting. The response\
1336 \ body contains " ++ show (BS.length body) ++ " bytes. Here is the "
1337 ++ if BS.length body <= 76 then "whole thing:" else "beginning:"
1338 , D.indent 4 $ D.dullyellow $ D.fromChars $
1339 if BS.length body <= 76
1340 then BS_UTF8.toString body
1341 else take 73 (BS_UTF8.toString body) ++ "..."
1342 , D.reflow $
1343 "Does this error keep showing up? Maybe there is something weird with your\
1344 \ internet connection. We have gotten reports that schools, businesses,\
1345 \ airports, etc. sometimes intercept requests and add things to the body\
1346 \ or change its contents entirely. Could that be the problem?"
1350toHttpErrorReport :: String -> Http.Error -> String -> Help.Report
1351toHttpErrorReport title err context =
1352 let
1353 toHttpReport intro url details =
1354 Help.report title Nothing intro $
1355 D.indent 4 (D.dullyellow (D.fromChars url)) : details
1356 in
1357 case err of
1358 Http.BadUrl url reason ->
1359 toHttpReport (context ++ ", so I wanted to fetch:") url
1360 [ D.reflow $ "But my HTTP library is saying this is not a valid URL. It is saying:"
1361 , D.indent 4 $ D.fromChars reason
1362 , D.reflow $
1363 "This may indicate that there is some problem in the compiler, so please open an\
1364 \ issue at https://github.com/elm/compiler/issues listing your operating system, Elm\
1365 \ version, the command you ran, the terminal output, and any additional information\
1366 \ that might help others reproduce the error."
1369 Http.BadHttp url httpExceptionContent ->
1370 case httpExceptionContent of
1371 HTTP.StatusCodeException response _ ->
1372 let
1373 (HTTP.Status code message) = HTTP.responseStatus response
1374 in
1375 toHttpReport (context ++ ", so I tried to fetch:") url
1376 [ D.fillSep $
1377 ["But","it","came","back","as",D.red (D.fromInt code)]
1378 ++ map D.fromChars (words (BS_UTF8.toString message))
1379 , D.reflow $
1380 "This may mean some online endpoint changed in an unexpected way, so if does not\
1381 \ seem like something on your side is causing this (e.g. firewall) please report\
1382 \ this to https://github.com/elm/compiler/issues with your operating system, Elm\
1383 \ version, the command you ran, the terminal output, and any additional information\
1384 \ that can help others reproduce the error!"
1387 HTTP.TooManyRedirects responses ->
1388 toHttpReport (context ++ ", so I tried to fetch:") url
1389 [ D.reflow $ "But I gave up after following these " ++ show (length responses) ++ " redirects:"
1390 , D.indent 4 $ D.vcat $ map toRedirectDoc responses
1391 , D.reflow $
1392 "Is it possible that your internet connection intercepts certain requests? That\
1393 \ sometimes causes problems for folks in schools, businesses, airports, hotels,\
1394 \ and certain countries. Try asking for help locally or in a community forum!"
1397 otherException ->
1398 toHttpReport (context ++ ", so I tried to fetch:") url
1399 [ D.reflow $ "But my HTTP library is giving me the following error message:"
1400 , D.indent 4 $ D.fromChars (show otherException)
1401 , D.reflow $
1402 "Are you somewhere with a slow internet connection? Or no internet?\
1403 \ Does the link I am trying to fetch work in your browser? Maybe the\
1404 \ site is down? Does your internet connection have a firewall that\
1405 \ blocks certain domains? It is usually something like that!"
1408 Http.BadMystery url someException ->
1409 toHttpReport (context ++ ", so I tried to fetch:") url
1410 [ D.reflow $ "But I ran into something weird! I was able to extract this error message:"
1411 , D.indent 4 $ D.fromChars (show someException)
1412 , D.reflow $
1413 "Is it possible that your internet connection intercepts certain requests? That\
1414 \ sometimes causes problems for folks in schools, businesses, airports, hotels,\
1415 \ and certain countries. Try asking for help locally or in a community forum!"
1419toRedirectDoc :: HTTP.Response body -> D.Doc
1420toRedirectDoc response =
1421 let
1422 (HTTP.Status code message) = HTTP.responseStatus response
1423 in
1424 case List.lookup HTTP.hLocation (HTTP.responseHeaders response) of
1425 Just loc -> D.red (D.fromInt code) <> " - " <> D.fromChars (BS_UTF8.toString loc)
1426 Nothing -> D.red (D.fromInt code) <> " - " <> D.fromChars (BS_UTF8.toString message)
1430-- MAKE
1433data Make
1434 = MakeNoOutline
1435 | MakeCannotOptimizeAndDebug
1436 | MakeBadDetails Details
1437 | MakeAppNeedsFileNames
1438 | MakePkgNeedsExposing
1439 | MakeMultipleFilesIntoHtml
1440 | MakeNonMainFilesIntoJavaScript ModuleName.Raw [ModuleName.Raw]
1441 | MakeCannotBuild BuildProblem
1442 | MakeBadGenerate Generate
1445makeToReport :: Make -> Help.Report
1446makeToReport make =
1447 case make of
1448 MakeNoOutline ->
1449 Help.report "NO elm.json FILE" Nothing
1450 "It looks like you are starting a new Elm project. Very exciting! Try running:"
1451 [ D.indent 4 $ D.green $ "elm init"
1452 , D.reflow $
1453 "It will help you get set up. It is really simple!"
1456 MakeCannotOptimizeAndDebug ->
1457 Help.docReport "CLASHING FLAGS" Nothing
1458 ( D.fillSep
1459 ["I","cannot","compile","with",D.red "--optimize","and"
1460 ,D.red "--debug","at","the","same","time."
1463 [ D.reflow
1464 "I need to take away information to optimize things, and I need to\
1465 \ add information to add the debugger. It is impossible to do both\
1466 \ at once though! Pick just one of those flags and it should work!"
1469 MakeBadDetails detailsProblem ->
1470 toDetailsReport detailsProblem
1472 MakeAppNeedsFileNames ->
1473 Help.report "NO INPUT" Nothing
1474 "What should I make though? I need a specific file like this:"
1475 [ D.indent 4 $ D.green "elm make src/Main.elm"
1476 , D.reflow
1477 "However many files you give, I will create one JS file out of them."
1480 MakePkgNeedsExposing ->
1481 error "TODO MakePkgNeedsExposing"
1483 MakeMultipleFilesIntoHtml ->
1484 error "TODO MakeMultipleFilesIntoHtml"
1486 MakeNonMainFilesIntoJavaScript _ _ ->
1487 error "TODO MakeNonMainFilesIntoJavaScript"
1489 MakeCannotBuild buildProblem ->
1490 toBuildProblemReport buildProblem
1492 MakeBadGenerate generateProblem ->
1493 toGenerateReport generateProblem
1497-- BUILD PROBLEM
1500data BuildProblem
1501 = BuildBadModules Error.Module [Error.Module]
1502 | BuildProjectProblem BuildProjectProblem
1505data BuildProjectProblem
1506 = BP_PathUnknown FilePath
1507 | BP_WithBadExtension FilePath
1508 | BP_WithAmbiguousSrcDir FilePath FilePath FilePath
1509 | BP_MainPathDuplicate FilePath FilePath
1510 | BP_MainNameDuplicate ModuleName.Raw FilePath FilePath
1511 | BP_CannotLoadDependencies
1512 | BP_Cycle ModuleName.Raw [ModuleName.Raw]
1513 | BP_MissingExposed (NE.List (ModuleName.Raw, Import.Problem))
1516toBuildProblemReport :: BuildProblem -> Help.Report
1517toBuildProblemReport problem =
1518 case problem of
1519 BuildBadModules e es ->
1520 Help.compilerReport e es
1522 BuildProjectProblem projectProblem ->
1523 toProjectProblemReport projectProblem
1526toProjectProblemReport :: BuildProjectProblem -> Help.Report
1527toProjectProblemReport projectProblem =
1528 case projectProblem of
1529 BP_PathUnknown path ->
1530 Help.report "FILE NOT FOUND" Nothing
1531 "I cannot find this file:"
1532 [ D.indent 4 $ D.red $ D.fromChars path
1533 , D.reflow $ "Is there a typo?"
1534 , D.toSimpleNote $
1535 "If you are just getting started, try working through the examples in the\
1536 \ official guide https://guide.elm-lang.org to get an idea of the kinds of things\
1537 \ that typically go in a src/Main.elm file."
1540 BP_WithBadExtension path ->
1541 Help.report "UNEXPECTED FILE EXTENSION" Nothing
1542 "I can only compile Elm files (with a .elm extension) but you want me to compile:"
1543 [ D.indent 4 $ D.red $ D.fromChars path
1544 , D.reflow $ "Is there a typo? Can the file extension be changed?"
1547 BP_WithAmbiguousSrcDir path srcDir1 srcDir2 ->
1548 Help.report "CONFUSING FILE" Nothing
1549 "I am getting confused when I try to compile this file:"
1550 [ D.indent 4 $ D.red $ D.fromChars path
1551 , D.reflow $
1552 "I always check if files appear in any of the \"source-directories\" listed in\
1553 \ your elm.json to see if there might be some cached information about them. That\
1554 \ can help me compile faster! But in this case, it looks like this file may be in\
1555 \ either of these directories:"
1556 , D.indent 4 $ D.red $ D.vcat $ map D.fromChars [srcDir1,srcDir2]
1557 , D.reflow $
1558 "Try to make it so no source directory contains another source directory!"
1561 BP_MainPathDuplicate path1 path2 ->
1562 Help.report "CONFUSING FILES" Nothing
1563 "You are telling me to compile these two files:"
1564 [ D.indent 4 $ D.red $ D.vcat $ map D.fromChars [ path1, path2 ]
1565 , D.reflow $
1566 if path1 == path2 then
1567 "Why are you telling me twice? Is something weird going on with a script?\
1568 \ I figured I would let you know about it just in case something is wrong.\
1569 \ Only list it once and you should be all set!"
1570 else
1571 "But seem to be the same file though... It makes me think something tricky is\
1572 \ going on with symlinks in your project, so I figured I would let you know\
1573 \ about it just in case. Remove one of these files from your command to get\
1574 \ unstuck!"
1577 BP_MainNameDuplicate name outsidePath otherPath ->
1578 Help.report "MODULE NAME CLASH" Nothing
1579 "These two files are causing a module name clash:"
1580 [ D.indent 4 $ D.red $ D.vcat $ map D.fromChars [ outsidePath, otherPath ]
1581 , D.reflow $
1582 "They both say `module " ++ ModuleName.toChars name ++ " exposing (..)` up\
1583 \ at the top, but they cannot have the same name!"
1584 , D.reflow $
1585 "Try changing to a different module name in one of them!"
1588 BP_CannotLoadDependencies ->
1589 corruptCacheReport
1591 BP_Cycle name names ->
1592 Help.report "IMPORT CYCLE" Nothing
1593 "Your module imports form a cycle:"
1594 [ D.cycle 4 name names
1595 , D.reflow $
1596 "Learn more about why this is disallowed and how to break cycles here:"
1597 ++ D.makeLink "import-cycles"
1600 BP_MissingExposed (NE.List (name, problem) _) ->
1601 case problem of
1602 Import.NotFound ->
1603 Help.report "MISSING MODULE" (Just "elm.json")
1604 "The \"exposed-modules\" of your elm.json lists the following module:"
1605 [ D.indent 4 $ D.red $ D.fromName name
1606 , D.reflow $
1607 "But I cannot find it in your src/ directory. Is there a typo? Was it renamed?"
1610 Import.Ambiguous _ _ pkg _ ->
1611 Help.report "AMBIGUOUS MODULE NAME" (Just "elm.json")
1612 "The \"exposed-modules\" of your elm.json lists the following module:"
1613 [ D.indent 4 $ D.red $ D.fromName name
1614 , D.reflow $
1615 "But a module from " ++ Pkg.toChars pkg ++ " already uses that name. Try\
1616 \ choosing a different name for your local file."
1619 Import.AmbiguousLocal path1 path2 paths ->
1620 Help.report "AMBIGUOUS MODULE NAME" (Just "elm.json")
1621 "The \"exposed-modules\" of your elm.json lists the following module:"
1622 [ D.indent 4 $ D.red $ D.fromName name
1623 , D.reflow $
1624 "But I found multiple files with that name:"
1625 , D.dullyellow $ D.indent 4 $ D.vcat $
1626 map D.fromChars (path1:path2:paths)
1627 , D.reflow $
1628 "Change the module names to be distinct!"
1631 Import.AmbiguousForeign _ _ _ ->
1632 Help.report "MISSING MODULE" (Just "elm.json")
1633 "The \"exposed-modules\" of your elm.json lists the following module:"
1634 [ D.indent 4 $ D.red $ D.fromName name
1635 , D.reflow $
1636 "But I cannot find it in your src/ directory. Is there a typo? Was it renamed?"
1637 , D.toSimpleNote $
1638 "It is not possible to \"re-export\" modules from other packages. You can only\
1639 \ expose modules that you define in your own code."
1644-- GENERATE
1647data Generate
1648 = GenerateCannotLoadArtifacts
1649 | GenerateCannotOptimizeDebugValues ModuleName.Raw [ModuleName.Raw]
1652toGenerateReport :: Generate -> Help.Report
1653toGenerateReport problem =
1654 case problem of
1655 GenerateCannotLoadArtifacts ->
1656 corruptCacheReport
1658 GenerateCannotOptimizeDebugValues m ms ->
1659 Help.report "DEBUG REMNANTS" Nothing
1660 "There are uses of the `Debug` module in the following modules:"
1661 [ D.indent 4 $ D.red $ D.vcat $ map (D.fromChars . ModuleName.toChars) (m:ms)
1662 , D.reflow "But the --optimize flag only works if all `Debug` functions are removed!"
1663 , D.toSimpleNote $
1664 "The issue is that --optimize strips out info needed by `Debug` functions.\
1665 \ Here are two examples:"
1666 , D.indent 4 $ D.reflow $
1667 "(1) It shortens record field names. This makes the generated JavaScript is\
1668 \ smaller, but `Debug.toString` cannot know the real field names anymore."
1669 , D.indent 4 $ D.reflow $
1670 "(2) Values like `type Height = Height Float` are unboxed. This reduces\
1671 \ allocation, but it also means that `Debug.toString` cannot tell if it is\
1672 \ looking at a `Height` or `Float` value."
1673 , D.reflow $
1674 "There are a few other cases like that, and it will be much worse once we start\
1675 \ inlining code. That optimization could move `Debug.log` and `Debug.todo` calls,\
1676 \ resulting in unpredictable behavior. I hope that clarifies why this restriction\
1677 \ exists!"
1682-- CORRUPT CACHE
1685corruptCacheReport :: Help.Report
1686corruptCacheReport =
1687 Help.report "CORRUPT CACHE" Nothing
1688 "It looks like some of the information cached in elm-stuff/ has been corrupted."
1689 [ D.reflow $
1690 "Try deleting your elm-stuff/ directory to get unstuck."
1691 , D.toSimpleNote $
1692 "This almost certainly means that a 3rd party tool (or editor plugin) is\
1693 \ causing problems your the elm-stuff/ directory. Try disabling 3rd party tools\
1694 \ one by one until you figure out which it is!"
1699-- REACTOR
1702data Reactor
1703 = ReactorNoOutline
1704 | ReactorBadDetails Details
1705 | ReactorBadBuild BuildProblem
1706 | ReactorBadGenerate Generate
1709reactorToReport :: Reactor -> Help.Report
1710reactorToReport problem =
1711 case problem of
1712 ReactorNoOutline ->
1713 Help.report "NEW PROJECT?" Nothing
1714 "Are you trying to start a new project? Try this command in the terminal:"
1715 [ D.indent 4 $ D.green "elm init"
1716 , D.reflow "It will help you get started!"
1719 ReactorBadDetails details ->
1720 toDetailsReport details
1722 ReactorBadBuild buildProblem ->
1723 toBuildProblemReport buildProblem
1725 ReactorBadGenerate generate ->
1726 toGenerateReport generate
1730-- REPL
1733data Repl
1734 = ReplBadDetails Details
1735 | ReplBadInput BS.ByteString Error.Error
1736 | ReplBadLocalDeps Error.Module [Error.Module]
1737 | ReplProjectProblem BuildProjectProblem
1738 | ReplBadGenerate Generate
1739 | ReplBadCache
1740 | ReplBlocked
1743replToReport :: Repl -> Help.Report
1744replToReport problem =
1745 case problem of
1746 ReplBadDetails details ->
1747 toDetailsReport details
1749 ReplBadInput source err ->
1750 Help.compilerReport (Error.Module N.replModule "REPL" File.zeroTime source err) []
1752 ReplBadLocalDeps e es ->
1753 Help.compilerReport e es
1755 ReplProjectProblem projectProblem ->
1756 toProjectProblemReport projectProblem
1758 ReplBadGenerate generate ->
1759 toGenerateReport generate
1761 ReplBadCache ->
1762 corruptCacheReport
1764 ReplBlocked ->
1765 corruptCacheReport