Rename gren publish to gren package validate.

This commit is contained in:
Robin Heggelund Hansen 2022-09-09 20:05:11 +02:00
parent 2d8b9d5eb6
commit a0f300fe01
4 changed files with 143 additions and 206 deletions

View File

@ -11,8 +11,8 @@ module Reporting.Exit
bumpToReport,
Repl (..),
replToReport,
Publish (..),
publishToReport,
Validate (..),
validateToReport,
Install (..),
installToReport,
Format (..),
@ -169,8 +169,7 @@ diffToReport diff =
"CANNOT DIFF APPLICATIONS"
(Just "gren.json")
"Your gren.json says this project is an application, but `gren diff` only works\
\ with packages. That way there are previously published versions of the API to\
\ diff against!"
\ with packages."
[ D.reflow $ "If you are just curious to see a diff, try running this command:",
D.indent 4 $ D.dullyellow $ "gren diff gren/json 1.0.0 1.1.2"
]
@ -185,9 +184,9 @@ diffToReport diff =
]
DiffUnpublished ->
Help.report
"UNPUBLISHED"
"UNTAGGED"
Nothing
"This package is not published yet. There is nothing to diff against!"
"This package has no semver formatted tags. There is nothing to diff against!"
[]
DiffUnknownPackage pkg suggestions ->
Help.report
@ -205,12 +204,10 @@ diffToReport diff =
"UNKNOWN VERSION"
Nothing
( D.fillSep $
[ "Version",
[ "Found",
"no",
D.red (D.fromVersion vsn),
"has",
"never",
"been",
"published,",
"tag",
"so",
"I",
"cannot",
@ -219,7 +216,7 @@ diffToReport diff =
"it."
]
)
[ "Here are all the versions that HAVE been published:",
[ "Here are all the semver formatted tags I did find:",
D.indent 4 $
D.dullyellow $
D.vcat $
@ -267,8 +264,9 @@ bumpToReport bump =
Help.report
"CANNOT BUMP APPLICATIONS"
(Just "gren.json")
"Your gren.json says this is an application. That means it cannot be published\
\ on <https://package.gren-lang.org> and therefore has no version to bump!"
"Your gren.json says this is an application. That means it cannot be used\
\ installed as a dependency in another project. There's no need to handle\
\ versioning of applications."
[]
BumpUnexpectedVersion vsn versions ->
Help.docReport
@ -361,7 +359,7 @@ bumpToReport bump =
newPackageOverview :: String
newPackageOverview =
unlines
[ "This package has never been published before. Here's how things work:",
[ "This package hasn't been tagged with a semver version. Here's how things work:",
"",
" - Versions all have exactly three parts: MAJOR.MINOR.PATCH",
"",
@ -377,54 +375,57 @@ newPackageOverview =
""
]
-- PUBLISH
-- VALIDATE
data Publish
= PublishNoOutline
| PublishBadOutline Outline
| PublishBadDetails Details
| PublishApplication
| PublishNotInitialVersion V.Version
| PublishAlreadyPublished V.Version
| PublishInvalidBump V.Version V.Version
| PublishBadBump V.Version V.Version M.Magnitude V.Version M.Magnitude
| PublishNoSummary
| PublishNoExposed
| PublishNoReadme
| PublishShortReadme
| PublishNoLicense
| PublishBuildProblem BuildProblem
| PublishCannotGetDocs V.Version V.Version DocsProblem
| PublishMissingTag V.Version
| PublishNoGit
| PublishLocalChanges V.Version
data Validate
= ValidateNoOutline
| ValidateBadOutline Outline
| ValidateBadDetails Details
| ValidateApplication
| ValidateNotInitialVersion V.Version
| ValidateInvalidBump V.Version V.Version
| ValidateBadBump V.Version V.Version M.Magnitude V.Version M.Magnitude
| ValidateNoSummary
| ValidateNoExposed
| ValidateNoReadme
| ValidateShortReadme
| ValidateNoLicense
| ValidateBuildProblem BuildProblem
| ValidateCannotGetDocs V.Version V.Version DocsProblem
| ValidateMissingTag V.Version
| ValidateNoGit
| ValidateLocalChanges V.Version
publishToReport :: Publish -> Help.Report
publishToReport publish =
case publish of
PublishNoOutline ->
validateToReport :: Validate -> Help.Report
validateToReport validate =
case validate of
ValidateNoOutline ->
Help.report
"PUBLISH WHAT?"
"VALIDATE WHAT?"
Nothing
"I cannot find an gren.json so I am not sure what you want me to publish."
"I cannot find an gren.json so I am not sure what you want me to validate."
[ D.reflow $
"Gren packages always have an gren.json that states the version number,\
\ dependencies, exposed modules, etc."
]
PublishBadOutline outline ->
ValidateBadOutline outline ->
toOutlineReport outline
PublishBadDetails problem ->
ValidateBadDetails problem ->
toDetailsReport problem
PublishApplication ->
Help.report "UNPUBLISHABLE" Nothing "I cannot publish applications, only packages!" []
PublishNotInitialVersion vsn ->
ValidateApplication ->
Help.report
"NOT A PACKAGE"
Nothing
"I cannot validate applications, only packages!"
[]
ValidateNotInitialVersion vsn ->
Help.docReport
"INVALID VERSION"
Nothing
( D.fillSep
[ "I",
"cannot",
"publish",
"validate",
D.red (D.fromVersion vsn),
"as",
"the",
@ -448,33 +449,7 @@ publishToReport publish =
"packages."
]
]
PublishAlreadyPublished vsn ->
Help.docReport
"ALREADY PUBLISHED"
Nothing
( D.vcat
[ D.fillSep
[ "Version",
D.green (D.fromVersion vsn),
"has",
"already",
"been",
"published.",
"You",
"cannot",
"publish",
"it",
"again!"
],
"Try using the `bump` command:"
]
)
[ D.dullyellow $ D.indent 4 "gren bump",
D.reflow $
"It computes the version number based on API changes, ensuring\
\ that no breaking changes end up in PATCH releases!"
]
PublishInvalidBump statedVersion latestVersion ->
ValidateInvalidBump statedVersion latestVersion ->
Help.docReport
"INVALID VERSION"
(Just "gren.json")
@ -497,7 +472,7 @@ publishToReport publish =
"on",
"the",
"previously",
"published",
"tagged",
"versions."
]
)
@ -513,7 +488,7 @@ publishToReport publish =
"the",
"most",
"recently",
"published",
"tagged",
"version.",
"From",
"there,",
@ -530,7 +505,7 @@ publishToReport publish =
"If you want more insight on the API changes Gren detects, you\
\ can run `gren diff` at this point as well."
]
PublishBadBump old new magnitude realNew realMagnitude ->
ValidateBadBump old new magnitude realNew realMagnitude ->
Help.docReport
"INVALID VERSION"
(Just "gren.json")
@ -581,46 +556,34 @@ publishToReport publish =
"version",
"should",
"be",
D.green (D.fromVersion realNew) <> ".",
"Double",
"check",
"everything",
"to",
"make",
"sure",
"you",
"are",
"publishing",
"what",
"you",
"want!"
D.green (D.fromVersion realNew) <> "."
],
D.reflow $
"Also, next time use `gren bump` and I'll figure all this out for you!"
]
PublishNoSummary ->
ValidateNoSummary ->
Help.docReport
"NO SUMMARY"
(Just "gren.json")
( D.fillSep $
[ "To",
"publish",
"a",
[ "Every",
"package,",
"your",
"gren.json",
"must",
"should",
"have",
"a",
D.dullyellow "\"summary\"",
"field",
"in",
"the",
"gren.json",
"file",
"that",
"gives",
"a",
"consice",
"overview",
"of",
"your",
"the",
"project."
]
)
@ -628,16 +591,12 @@ publishToReport publish =
"The summary must be less than 80 characters. It should describe\
\ the concrete use of your package as clearly and as plainly as possible."
]
PublishNoExposed ->
ValidateNoExposed ->
Help.docReport
"NO EXPOSED MODULES"
(Just "gren.json")
( D.fillSep $
[ "To",
"publish",
"a",
"package,",
"the",
[ "The",
D.dullyellow "\"exposed-modules\"",
"field",
"of",
@ -655,19 +614,19 @@ publishToReport publish =
"Which modules do you want users of the package to have access to? Add their\
\ names to the \"exposed-modules\" list."
]
PublishNoReadme ->
ValidateNoReadme ->
toBadReadmeReport "NO README" $
"Every published package must have a helpful README.md\
"Every package should have a helpful README.md\
\ file, but I do not see one in your project."
PublishShortReadme ->
ValidateShortReadme ->
toBadReadmeReport "SHORT README" $
"This README.md is too short. Having more details will help\
\ people assess your package quickly and fairly."
PublishNoLicense ->
ValidateNoLicense ->
Help.report
"NO LICENSE FILE"
(Just "LICENSE")
"By publishing a package you are inviting the Gren community to build\
"By making a package available you are inviting the Gren community to build\
\ upon your work. But without knowing your license, we have no idea if\
\ that is legal!"
[ D.reflow $
@ -677,16 +636,16 @@ publishToReport publish =
\ license text must appear in the root of your project in a file\
\ named LICENSE. Add that file and you will be all set!"
]
PublishBuildProblem buildProblem ->
ValidateBuildProblem buildProblem ->
toBuildProblemReport buildProblem
PublishCannotGetDocs old new docsProblem ->
ValidateCannotGetDocs old new docsProblem ->
toDocsProblemReport docsProblem $
"I need the docs for "
++ V.toChars old
++ " to verify that "
++ V.toChars new
++ " really does come next"
PublishMissingTag version ->
ValidateMissingTag version ->
let vsn = V.toChars version
in Help.docReport
"NO TAG"
@ -720,7 +679,7 @@ publishToReport publish =
],
"The -m flag is for a helpful message. Try to make it more informative!"
]
PublishNoGit ->
ValidateNoGit ->
Help.report
"NO GIT"
Nothing
@ -734,7 +693,7 @@ publishToReport publish =
D.toSimpleNote $
"We plan to do this without the `git` binary in a future release."
]
PublishLocalChanges version ->
ValidateLocalChanges version ->
let vsn = V.toChars version
in Help.docReport
"LOCAL CHANGES"
@ -770,14 +729,12 @@ publishToReport publish =
"going",
"to",
"be",
"published!"
"available",
"when",
"downloaded!"
]
)
[ D.toSimpleNote $
"If you are sure everything is in order, you can run `git checkout "
++ vsn
++ "` and publish your code from there."
]
[]
toBadReadmeReport :: String -> String -> Help.Report
toBadReadmeReport title summary =
@ -796,10 +753,10 @@ toBadReadmeReport title summary =
\ most common usage scenario. Show people what they can expect if\
\ they learn more!",
D.toSimpleNote $
"By publishing your package, you are inviting people to invest time in\
"By tagging your package, you are inviting people to invest time in\
\ understanding your work. Spending an hour on your README to communicate your\
\ knowledge more clearly can save the community days or weeks of time in\
\ aggregate, and saving time in aggregate is the whole point of publishing\
\ aggregate, and saving time in aggregate is the whole point of building\
\ packages! People really appreciate it, and it makes the whole ecosystem feel\
\ nicer!"
]
@ -860,7 +817,6 @@ data Install
| InstallHadSolverTrouble Solver
| InstallNoCompatiblePkg Pkg.Name
| InstallUnknownPackageOnline Pkg.Name [Pkg.Name]
| InstallUnknownPackageOffline Pkg.Name [Pkg.Name]
| InstallBadDetails Details
installToReport :: Install -> Help.Report
@ -886,7 +842,7 @@ installToReport exit =
\ with your existing dependencies."
)
[ D.reflow $
"I checked all the published versions. When that failed, I tried to find any\
"I checked all the semver-formatted tags. When that failed, I tried to find any\
\ compatible combination of these packages, even if it meant changing all your\
\ existing dependencies! That did not work either!",
D.reflow $
@ -951,21 +907,6 @@ installToReport exit =
D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromPackage suggestions,
D.reflow $ "Maybe you want one of these instead?"
]
InstallUnknownPackageOffline pkg suggestions ->
Help.docReport
"UNKNOWN PACKAGE"
Nothing
( D.fillSep
["I", "cannot", "find", "a", "package", "named", D.red (D.fromPackage pkg) <> "."]
)
[ D.reflow $
"I could not connect to https://package.gren-lang.org though, so new packages may\
\ have been published since I last updated my local cache of package names.",
D.reflow $
"Looking through the locally cached names, the closest ones are:",
D.indent 4 $ D.dullyellow $ D.vcat $ map D.fromPackage suggestions,
D.reflow $ "Maybe you want one of these instead?"
]
InstallBadDetails details ->
toDetailsReport details

View File

@ -58,7 +58,7 @@ Common gren-common
Install
Make
Docs
Publish
Validate
Repl
Package

View File

@ -9,10 +9,10 @@ import Bump qualified
import Data.List qualified as List
import Diff qualified
import Install qualified
import Publish qualified
import Terminal
import Terminal.Helpers
import Text.PrettyPrint.ANSI.Leijen qualified as P
import Validate qualified
-- RUN
@ -24,7 +24,7 @@ run =
[ install,
bump,
diff,
publish
validate
]
intro :: P.Doc
@ -68,37 +68,35 @@ install =
]
in Terminal.Command "install" (Common summary) details example installArgs noFlags Install.run
-- PUBLISH
-- VALIDATE
publish :: Terminal.Command
publish =
validate :: Terminal.Command
validate =
let details =
"The `publish` command publishes your package on <https://package.gren-lang.org>\
\ so that anyone in the Gren community can use it."
"The `validate` command checks that you have done everything necessary\
\ so that anyone in the Gren community can use your package."
example =
stack
[ reflow
"Think hard if you are ready to publish NEW packages though!",
"Gren packages are \"just\" git repositories hosted on github. As\
\ long as you've tagged your repository with semver formatted tags,\
\ anyone can add your package as a dependency.",
reflow
"Part of what makes Gren great is the packages ecosystem. The fact that\
\ there is usually one option (usually very well done) makes it way\
\ easier to pick packages and become productive. So having a million\
\ packages would be a failure in Gren. We do not need twenty of\
\ everything, all coded in a single weekend.",
"However, a package is no better than its documentation. This command\
\ therefore checks that your package exposes a bare minimum of\
\ prose that the users of your package can read.",
reflow
"So as community members gain wisdom through experience, we want\
\ them to share that through thoughtful API design and excellent\
\ documentation. It is more about sharing ideas and insights than\
\ just sharing code! The first step may be asking for advice from\
\ people you respect, or in community forums. The second step may\
\ be using it at work to see if it is as nice as you think. Maybe\
\ it ends up as an experiment on GitHub only. Point is, try to be\
\ respectful of the community and package ecosystem!",
"Keep in mind, you don't just want to tell people HOW to use\
\ your package. It's equally important to tell them WHY. What\
\ problem does it solve? Why should people use this particular\
\ package to solve their problem?",
reflow
"Check out <https://package.gren-lang.org/help/design-guidelines> for guidance on how to create great packages!"
"Once this command passes, you may want to add your repo to\
\ https://packages.gren-lang.org so it becomes easier for the Gren\
\ community to find your package, and its documentation."
]
in Terminal.Command "publish" Uncommon details example noArgs noFlags Publish.run
in Terminal.Command "validate" Uncommon details example noArgs noFlags Validate.run
-- BUMP
@ -125,9 +123,9 @@ diff =
example =
stack
[ reflow
"For example, to see what changed in the HTML package between\
"For example, to see what changed in the Browser package between\
\ versions 1.0.0 and 2.0.0, you can say:",
P.indent 4 $ P.green $ "gren diff gren/html 1.0.0 2.0.0",
P.indent 4 $ P.green $ "gren package diff gren-lang/browser 1.0.0 2.0.0",
reflow
"Sometimes a MAJOR change is not actually very big, so\
\ this can help you plan your upgrade timelines."

View File

@ -1,6 +1,6 @@
{-# LANGUAGE OverloadedStrings #-}
module Publish
module Validate
( run,
)
where
@ -37,9 +37,9 @@ import System.Info qualified as Info
run :: () -> () -> IO ()
run () () =
Reporting.attempt Exit.publishToReport $
Reporting.attempt Exit.validateToReport $
Task.run $
publish =<< getEnv
validate =<< getEnv
-- ENV
@ -49,29 +49,29 @@ data Env = Env
_outline :: Outline.Outline
}
getEnv :: Task.Task Exit.Publish Env
getEnv :: Task.Task Exit.Validate Env
getEnv =
do
root <- Task.mio Exit.PublishNoOutline Dirs.findRoot
root <- Task.mio Exit.ValidateNoOutline Dirs.findRoot
cache <- Task.io Dirs.getPackageCache
outline <- Task.eio Exit.PublishBadOutline $ Outline.read root
outline <- Task.eio Exit.ValidateBadOutline $ Outline.read root
return $ Env root cache outline
-- PUBLISH
-- VALIDATE
publish :: Env -> Task.Task Exit.Publish ()
publish env@(Env root _ outline) =
validate :: Env -> Task.Task Exit.Validate ()
validate env@(Env root _ outline) =
case outline of
Outline.App _ ->
Task.throw Exit.PublishApplication
Task.throw Exit.ValidateApplication
Outline.Pkg (Outline.PkgOutline pkg summary _ vsn exposed _ _ _) ->
do
knownVersionsResult <- Task.io $ Package.getVersions pkg
let knownVersionsMaybe = Either.either (const Nothing) Just knownVersionsResult
reportPublishStart pkg vsn knownVersionsMaybe
reportValidateStart pkg vsn knownVersionsMaybe
if noExposed exposed then Task.throw Exit.PublishNoExposed else return ()
if badSummary summary then Task.throw Exit.PublishNoSummary else return ()
if noExposed exposed then Task.throw Exit.ValidateNoExposed else return ()
if badSummary summary then Task.throw Exit.ValidateNoSummary else return ()
verifyReadme root
verifyLicense root
@ -98,23 +98,23 @@ noExposed exposed =
-- VERIFY README
verifyReadme :: FilePath -> Task.Task Exit.Publish ()
verifyReadme :: FilePath -> Task.Task Exit.Validate ()
verifyReadme root =
reportReadmeCheck $
do
let readmePath = root </> "README.md"
exists <- File.exists readmePath
if not exists
then return (Left Exit.PublishNoReadme)
then return (Left Exit.ValidateNoReadme)
else do
size <- IO.withFile readmePath IO.ReadMode IO.hFileSize
if size < 300
then return (Left Exit.PublishShortReadme)
then return (Left Exit.ValidateShortReadme)
else return (Right ())
-- VERIFY LICENSE
verifyLicense :: FilePath -> Task.Task Exit.Publish ()
verifyLicense :: FilePath -> Task.Task Exit.Validate ()
verifyLicense root =
reportLicenseCheck $
do
@ -122,56 +122,56 @@ verifyLicense root =
exists <- File.exists licensePath
if exists
then return (Right ())
else return (Left Exit.PublishNoLicense)
else return (Left Exit.ValidateNoLicense)
-- VERIFY BUILD
verifyBuild :: FilePath -> Task.Task Exit.Publish Docs.Documentation
verifyBuild :: FilePath -> Task.Task Exit.Validate Docs.Documentation
verifyBuild root =
reportBuildCheck $
BW.withScope $ \scope ->
Task.run $
do
details@(Details.Details _ outline _ _ _ _) <-
Task.eio Exit.PublishBadDetails $
Task.eio Exit.ValidateBadDetails $
Details.load Reporting.silent scope root
exposed <-
case outline of
Details.ValidApp _ _ -> Task.throw Exit.PublishApplication
Details.ValidPkg _ _ [] -> Task.throw Exit.PublishNoExposed
Details.ValidApp _ _ -> Task.throw Exit.ValidateApplication
Details.ValidPkg _ _ [] -> Task.throw Exit.ValidateNoExposed
Details.ValidPkg _ _ (e : es) -> return (NE.List e es)
Task.eio Exit.PublishBuildProblem $
Task.eio Exit.ValidateBuildProblem $
Build.fromExposed Reporting.silent root details Build.KeepDocs exposed
-- VERIFY LOCAL TAG
verifyTag :: V.Version -> Task.Task Exit.Publish ()
verifyTag :: V.Version -> Task.Task Exit.Validate ()
verifyTag vsn =
reportTagCheck vsn $
do
result <- Git.hasLocalTag vsn
case result of
Left Git.MissingGit ->
return $ Left Exit.PublishNoGit
return $ Left Exit.ValidateNoGit
Left _ ->
return $ Left $ Exit.PublishMissingTag vsn
return $ Left $ Exit.ValidateMissingTag vsn
Right () ->
return $ Right ()
-- VERIFY NO LOCAL CHANGES SINCE TAG
verifyNoChanges :: V.Version -> Task.Task Exit.Publish ()
verifyNoChanges :: V.Version -> Task.Task Exit.Validate ()
verifyNoChanges vsn =
reportLocalChangesCheck $
do
result <- Git.hasLocalChangesSinceTag vsn
case result of
Left Git.MissingGit ->
return $ Left Exit.PublishNoGit
return $ Left Exit.ValidateNoGit
Left _ ->
return $ Left $ Exit.PublishLocalChanges vsn
return $ Left $ Exit.ValidateLocalChanges vsn
Right () ->
return $ Right ()
@ -181,32 +181,30 @@ data GoodVersion
= GoodStart
| GoodBump V.Version M.Magnitude
verifyVersion :: Env -> Pkg.Name -> V.Version -> Docs.Documentation -> Maybe (V.Version, [V.Version]) -> Task.Task Exit.Publish ()
verifyVersion :: Env -> Pkg.Name -> V.Version -> Docs.Documentation -> Maybe (V.Version, [V.Version]) -> Task.Task Exit.Validate ()
verifyVersion env pkg vsn newDocs publishedVersions =
reportSemverCheck vsn $
case publishedVersions of
Nothing ->
if vsn == V.one
then return $ Right GoodStart
else return $ Left $ Exit.PublishNotInitialVersion vsn
Just vsns@(latest, previous) ->
if vsn == latest || elem vsn previous
then return $ Left $ Exit.PublishAlreadyPublished vsn
else verifyBump env pkg vsn newDocs vsns
else return $ Left $ Exit.ValidateNotInitialVersion vsn
Just vsns ->
verifyBump env pkg vsn newDocs vsns
verifyBump :: Env -> Pkg.Name -> V.Version -> Docs.Documentation -> (V.Version, [V.Version]) -> IO (Either Exit.Publish GoodVersion)
verifyBump :: Env -> Pkg.Name -> V.Version -> Docs.Documentation -> (V.Version, [V.Version]) -> IO (Either Exit.Validate GoodVersion)
verifyBump (Env _ cache _) pkg vsn newDocs knownVersions@(latest, _) =
case List.find (\(_, new, _) -> vsn == new) (Package.bumpPossibilities knownVersions) of
Nothing ->
return $
Left $
Exit.PublishInvalidBump vsn latest
Exit.ValidateInvalidBump vsn latest
Just (old, new, magnitude) ->
do
result <- Task.run $ Diff.getDocs cache pkg old
case result of
Left dp ->
return $ Left $ Exit.PublishCannotGetDocs old new dp
return $ Left $ Exit.ValidateCannotGetDocs old new dp
Right oldDocs ->
let changes = Diff.diff oldDocs newDocs
realNew = Diff.bump changes old
@ -215,12 +213,12 @@ verifyBump (Env _ cache _) pkg vsn newDocs knownVersions@(latest, _) =
else
return $
Left $
Exit.PublishBadBump old new magnitude realNew (Diff.toMagnitude changes)
Exit.ValidateBadBump old new magnitude realNew (Diff.toMagnitude changes)
-- REPORTING
reportPublishStart :: Pkg.Name -> V.Version -> Maybe (V.Version, [V.Version]) -> Task.Task x ()
reportPublishStart pkg vsn maybeKnownVersions =
reportValidateStart :: Pkg.Name -> V.Version -> Maybe (V.Version, [V.Version]) -> Task.Task x ()
reportValidateStart pkg vsn maybeKnownVersions =
Task.io $
case maybeKnownVersions of
Nothing ->