@@ -0,0 +1,243 @@
1+{-# OPTIONS_GHC -Wall #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+module Reporting.Error.Publish
10+import qualified Text.PrettyPrint.ANSI.Leijen as P
11+import Text.PrettyPrint.ANSI.Leijen ((<>))
13+import Deps.Diff (Magnitude, magnitudeToString)
14+import qualified Elm.Package as Pkg
15+import qualified Reporting.Error.Help as Help
24+ | NotInitialVersion Pkg.Version
25+ | AlreadyPublished Pkg.Version
26+ | InvalidBump Pkg.Version Pkg.Version
27+ | BadBump Pkg.Version Pkg.Version Magnitude Pkg.Version Magnitude
33+ | MissingTag Pkg.Version
35+ | LocalChanges Pkg.Version
42+toReport :: Error -> Help.Report
46+ Help.report "UNPUBLISHABLE" Nothing "I cannot publish applications, only packages!" []
48+ NotInitialVersion vsn ->
49+ Help.docReport "INVALID VERSION" Nothing
51+ ["I","cannot","publish"
52+ ,P.red (P.text (Pkg.versionToString vsn))
53+ ,"as","the","initial","version."
57+ ["Change","it","to",P.green "1.0.0","which","is"
58+ ,"the","initial","version","for","all","Elm","packages."
62+ AlreadyPublished vsn ->
63+ Help.docReport "ALREADY PUBLISHED" Nothing
66+ [ "Version", P.green (P.text (Pkg.versionToString vsn))
67+ , "has", "already", "been", "published.", "You", "cannot"
68+ , "publish", "it", "again!"
70+ , "Try using the `bump` command:"
73+ [ P.dullyellow $ P.indent 4 $ P.text "elm bump"
75+ "It computes the version number based on API changes, ensuring\
76+ \ that no breaking changes end up in PATCH releases!"
79+ InvalidBump statedVersion latestVersion ->
80+ Help.docReport "INVALID VERSION" (Just "elm.json")
82+ ["Your","elm.json","says","the","next","version","should","be"
83+ ,P.red (P.text (Pkg.versionToString statedVersion)) <> ","
84+ ,"but","that","is","not","valid","based","on","the","previously"
85+ ,"published","versions."
89+ ["Change","the","version","back","to"
90+ ,P.green (P.text (Pkg.versionToString latestVersion))
91+ ,"which","is","the","most","recently","published","version."
92+ ,"From","there,","have","Elm","bump","the","version","by","running:"
94+ , P.indent 4 $ P.green "elm bump"
96+ "If you want more insight on the API changes Elm detects, you\
97+ \ can run `elm diff` at this point as well."
100+ BadBump old new magnitude realNew realMagnitude ->
101+ Help.docReport "INVALID VERSION" (Just "elm.json")
104+ ["Your","elm.json","says","the","next","version","should","be"
105+ ,P.red (P.text (Pkg.versionToString new)) <> ","
106+ ,"indicating","a",P.text (magnitudeToString magnitude)
107+ ,"change","to","the","public","API."
108+ ,"This","does","not","match","the","API","diff","given","by:"
111+ [ P.indent 4 $ P.text $
112+ "elm diff " ++ Pkg.versionToString old
115+ ["This","command","says","this","is","a"
116+ ,P.text (magnitudeToString realMagnitude)
117+ ,"change,","so","the","next","version","should","be"
118+ ,P.green (P.text (Pkg.versionToString realNew)) <> "."
119+ ,"Double","check","everything","to","make","sure","you"
120+ ,"are","publishing","what","you","want!"
123+ "Also, next time use `elm bump` and I'll figure all this out for you!"
127+ Help.docReport "NO SUMMARY" (Just "elm.json")
129+ [ "To", "publish", "a", "package,", "your", "elm.json", "must"
130+ , "have", "a", P.dullyellow "\"summary\"", "field", "that", "gives"
131+ , "a", "consice", "overview", "of", "your", "project."
135+ "The summary must be less than 80 characters. It should describe\
136+ \ the concrete use of your package as clearly and as plainly as possible."
140+ Help.docReport "NO EXPOSED MODULES" (Just "elm.json")
142+ [ "To", "publish", "a", "package,", "the"
143+ , P.dullyellow "\"exposed-modules\"", "field", "of", "your"
144+ , "elm.json", "must", "list", "at", "least", "one", "module."
148+ "What is the point of a package that has no modules?!"
152+ badReadmeReport "NO README" $
153+ "Every published package must have a helpful README.md\
154+ \ file, but I do not see one in your project."
157+ badReadmeReport "SHORT README" $
158+ "This README.md is too short. Having more details will help\
159+ \ people assess your package quickly and fairly."
162+ Help.report "NO LICENSE FILE" (Just "LICENSE")
163+ "By publishing a package you are inviting the Elm community to build\
164+ \ upon your work. But without knowing your license, we have no idea if\
167+ "Once you pick an OSI approved license from <https://spdx.org/licenses/>,\
168+ \ you must share that choice in two places. First, the license\
169+ \ identifier must appear in your elm.json file. Second, the full\
170+ \ license text must appear in the root of your project in a file\
171+ \ named LICENSE. Add that file and you will be all set!"
174+ MissingTag version ->
175+ let vsn = Pkg.versionToString version in
176+ Help.docReport "NO TAG" Nothing
178+ [ "Packages", "must", "be", "tagged", "in", "git,", "but", "I"
179+ , "cannot", "find", "a", P.green (P.text vsn), "tag."
183+ [ "These tags make it possible to find this specific version on GitHub."
184+ , "To tag the most recent commit and push it to GitHub, run this:"
186+ , P.indent 4 $ P.dullyellow $ P.vcat $ map P.text $
187+ [ "git tag -a " ++ vsn ++ " -m \"release version " ++ vsn ++ "\""
188+ , "git push origin " ++ vsn
190+ , "The -m flag is for a helpful message. Try to make it more informative!"
194+ Help.report "NO GIT" Nothing
195+ "I searched your PATH environment variable for `git` and could not\
196+ \ find it. Is it available through your PATH?"
198+ "Who cares about this? Well, I currently use `git` to check if there\
199+ \ are any local changes in your code. Local changes are a good sign\
200+ \ that some important improvements have gotten mistagged, so this\
201+ \ check can be extremely helpful for package authors!"
203+ "We plan to do this without the `git` binary in a future release."
206+ LocalChanges version ->
207+ let vsn = Pkg.versionToString version in
208+ Help.docReport "LOCAL CHANGES" Nothing
210+ [ "The", "code", "tagged", "as", P.green (P.text vsn), "in"
211+ , "git", "does", "not", "match", "the", "code", "in", "your"
212+ , "working", "directory.", "This", "means", "you", "have"
213+ , "commits", "or", "local", "changes", "that", "are", "not"
214+ , "going", "to", "be", "published!"
218+ "If you are sure everything is in order, you can run `git checkout "
219+ ++ vsn ++ "` and publish your code from there."
223+badReadmeReport :: String -> String -> Help.Report
224+badReadmeReport title summary =
225+ Help.report title (Just "README.md") summary
227+ "When people look at your README, they are wondering:"
229+ [ " - What does this package even do?"
230+ , " - Will it help me solve MY problems?"
233+ "So I recommend starting your README with a small example of the\
234+ \ most common usage scenario. Show people what they can expect if\
237+ "By publishing your package, you are inviting people to invest time\
238+ \ in understanding your work. Spending an hour to communicate your\
239+ \ knowledge more clearly can save the community days or weeks of time\
240+ \ in aggregate, and saving time in aggregate is the whole point of\
241+ \ publishing packages! People really appreciate it, and it makes the\
242+ \ whole ecosystem feel nicer!"