1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
10import Control.Monad.Except (liftIO)
11import qualified Data.List as List
12import qualified Data.Map as Map
13import qualified Data.Maybe as Maybe
14import Text.PrettyPrint.ANSI.Leijen ((<>), (<+>))
15import qualified Text.PrettyPrint.ANSI.Leijen as P
17import Deps.Diff (PackageChanges(..), ModuleChanges(..), Changes(..), Magnitude(..))
18import qualified Deps.Diff as Diff
19import qualified Deps.Get as Get
20import qualified Elm.Compiler.Module as Module
21import qualified Elm.Compiler.Type as Type
22import qualified Elm.Docs as Docs
23import qualified Elm.Name as N
24import qualified Elm.Package as Pkg
25import qualified Elm.Project as Project
26import qualified Elm.Project.Json as Project
27import qualified Elm.Project.Summary as Summary
28import qualified Reporting.Exit as Exit
29import qualified Reporting.Exit.Diff as E
30import qualified Reporting.Exit.Help as Help
31import qualified Reporting.Task as Task
40 | CodeVsExactly Pkg.Version
41 | LocalInquiry Pkg.Version Pkg.Version
42 | GlobalInquiry Pkg.Name Pkg.Version Pkg.Version
45diff :: Args -> Task.Task ()
48 GlobalInquiry name v1 v2 ->
49 do pkgs <- Get.all Get.RequireLatest
50 case Get.versions name pkgs of
52 throw $ E.UnknownPackage name suggestions
55 do oldDocs <- getDocs name vsns (min v1 v2)
56 newDocs <- getDocs name vsns (max v1 v2)
57 writeDoc (toDoc (Diff.diff oldDocs newDocs))
60 do (_, name, vsns) <- getPackageInfo
61 oldDocs <- getDocs name vsns (min v1 v2)
62 newDocs <- getDocs name vsns (max v1 v2)
63 writeDoc (toDoc (Diff.diff oldDocs newDocs))
66 do (summary, name, vsns) <- getPackageInfo
67 oldDocs <- getDocs name vsns (maximum vsns)
68 newDocs <- Task.silently (Project.generateDocs summary)
69 writeDoc (toDoc (Diff.diff oldDocs newDocs))
71 CodeVsExactly version ->
72 do (summary, name, vsns) <- getPackageInfo
73 oldDocs <- getDocs name vsns version
74 newDocs <- Task.silently (Project.generateDocs summary)
75 writeDoc (toDoc (Diff.diff oldDocs newDocs))
78throw :: E.Exit -> Task.Task a
80 Task.throw $ Exit.Diff exit
87getDocs :: Pkg.Name -> [Pkg.Version] -> Pkg.Version -> Task.Task Docs.Documentation
88getDocs name allVersions version =
89 if elem version allVersions then
92 throw $ E.UnknownVersion name version allVersions
95getPackageInfo :: Task.Task (Summary.Summary, Pkg.Name, [Pkg.Version])
97 do summary <- Project.getRoot
98 case Summary._project summary of
100 throw $ E.Application
102 Project.Pkg (Project.PkgInfo name _ _ _ _ _ _ _) ->
103 do pkgs <- Get.all Get.RequireLatest
104 let vsns = either (const []) id (Get.versions name pkgs)
105 return ( summary, name, vsns )
112writeDoc :: P.Doc -> Task.Task ()
114 liftIO $ Help.toStdout (doc <> "\n")
121toDoc :: PackageChanges -> P.Doc
122toDoc changes@(PackageChanges added changed removed) =
123 if null added && Map.null changed && null removed then
124 "No API changes detected, so this is a" <+> P.green "PATCH" <+> "change."
128 P.text (Diff.magnitudeToString (Diff.toMagnitude changes))
131 "This is a" <+> P.green magDoc <+> "change."
134 if null added then [] else
135 [ Chunk "ADDED MODULES" MINOR $
136 P.vcat $ map (P.text . Module.nameToString) added
140 if null removed then [] else
141 [ Chunk "REMOVED MODULES" MAJOR $
142 P.vcat $ map (P.text . Module.nameToString) removed
146 addedChunk ++ removedChunk ++ map changesToChunk (Map.toList changed)
148 P.vcat (header : "" : map chunkToDoc chunks)
154 , _magnitude :: Magnitude
159chunkToDoc :: Chunk -> P.Doc
160chunkToDoc (Chunk title magnitude details) =
163 Diff.magnitudeToString magnitude
166 "----" <+> P.text title <+> "-" <+> P.text magDoc <+> "----"
177changesToChunk :: (N.Name, ModuleChanges) -> Chunk
178changesToChunk (name, changes@(ModuleChanges unions aliases values binops)) =
181 Diff.moduleChangeMagnitude changes
183 (unionAdd, unionChange, unionRemove) =
184 changesToDocTriple unionToDoc unions
186 (aliasAdd, aliasChange, aliasRemove) =
187 changesToDocTriple aliasToDoc aliases
189 (valueAdd, valueChange, valueRemove) =
190 changesToDocTriple valueToDoc values
192 (binopAdd, binopChange, binopRemove) =
193 changesToDocTriple binopToDoc binops
195 Chunk (N.toString name) magnitude $
196 P.vcat $ List.intersperse "" $ Maybe.catMaybes $
197 [ changesToDoc "Added" unionAdd aliasAdd valueAdd binopAdd
198 , changesToDoc "Removed" unionRemove aliasRemove valueRemove binopRemove
199 , changesToDoc "Changed" unionChange aliasChange valueChange binopChange
203changesToDocTriple :: (k -> v -> P.Doc) -> Changes k v -> ([P.Doc], [P.Doc], [P.Doc])
204changesToDocTriple entryToDoc (Changes added changed removed) =
206 indented (name, value) =
207 P.indent 4 (entryToDoc name value)
209 diffed (name, (oldValue, newValue)) =
211 [ " - " <> entryToDoc name oldValue
212 , " + " <> entryToDoc name newValue
216 ( map indented (Map.toList added)
217 , map diffed (Map.toList changed)
218 , map indented (Map.toList removed)
222changesToDoc :: String -> [P.Doc] -> [P.Doc] -> [P.Doc] -> [P.Doc] -> Maybe P.Doc
223changesToDoc categoryName unions aliases values binops =
224 if null unions && null aliases && null values && null binops then
229 P.text categoryName <> ":" : unions ++ aliases ++ binops ++ values
232unionToDoc :: N.Name -> Docs.Union -> P.Doc
233unionToDoc name (Docs.Union _ tvars ctors) =
236 "type" <+> nameToDoc name <+> P.hsep (map nameToDoc tvars)
238 ctorDoc (ctor, tipes) =
239 typeDoc (Type.Type ctor tipes)
241 P.hang 4 (P.sep (setup : zipWith (<+>) ("=" : repeat "|") (map ctorDoc ctors)))
244aliasToDoc :: N.Name -> Docs.Alias -> P.Doc
245aliasToDoc name (Docs.Alias _ tvars tipe) =
248 "type" <+> "alias" <+> P.hsep (map nameToDoc (name:tvars)) <+> "="
250 P.hang 4 (P.sep [ declaration, typeDoc tipe ])
253valueToDoc :: N.Name -> Docs.Value -> P.Doc
254valueToDoc name (Docs.Value _ tipe) =
255 P.hang 4 $ P.sep [ nameToDoc name <+> P.colon, typeDoc tipe ]
258binopToDoc :: N.Name -> Docs.Binop -> P.Doc
259binopToDoc name (Docs.Binop _ tipe associativity (Docs.Precedence n)) =
260 "(" <> nameToDoc name <> ")" <+> P.colon <+> typeDoc tipe <> P.black details
263 " (" <> nameToDoc assoc <> "/" <> P.int n <> ")"
266 case associativity of
269 Docs.Right -> "right"
272typeDoc :: Type.Type -> P.Doc
274 Type.toDoc Type.None tipe
277nameToDoc :: N.Name -> P.Doc
279 P.text (N.toString name)
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list