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 qualified Data.Name as Name
16import qualified Deps.Cache as Cache
17import Deps.Diff (PackageChanges(..), ModuleChanges(..), Changes(..), Magnitude(..))
18import qualified Deps.Diff as Diff
19import qualified Elm.Compiler.Type as Type
20import qualified Elm.Docs as Docs
21import qualified Elm.ModuleName as ModuleName
22import qualified Elm.Package as Pkg
23import qualified Elm.Project as Project
24import qualified Elm.Project.Json as Project
25import qualified Elm.Project.Summary as Summary
26import qualified Elm.Version as V
27import Reporting.Doc ((<>), (<+>))
28import qualified Reporting.Doc as D
29import qualified Reporting.Exit as Exit
30import qualified Reporting.Exit.Diff as E
31import qualified Reporting.Exit.Help as Help
32import qualified Reporting.Render.Type.Localizer as L
33import qualified Reporting.Task as Task
42 | CodeVsExactly V.Version
43 | LocalInquiry V.Version V.Version
44 | GlobalInquiry Pkg.Name V.Version V.Version
47diff :: Args -> Task.Task ()
50 GlobalInquiry name v1 v2 ->
51 do registry <- Cache.mandatoryUpdate
52 case Cache.getVersions name registry of
54 throw $ E.UnknownPackage name suggestions
57 do oldDocs <- getDocs name vsns (min v1 v2)
58 newDocs <- getDocs name vsns (max v1 v2)
59 writeDiff oldDocs newDocs
62 do (_, name, vsns) <- getPackageInfo
63 oldDocs <- getDocs name vsns (min v1 v2)
64 newDocs <- getDocs name vsns (max v1 v2)
65 writeDiff oldDocs newDocs
68 do (summary, name, vsns) <- getPackageInfo
69 oldDocs <- getDocs name vsns (maximum vsns)
70 newDocs <- Task.silently (error "TODO Project.generateDocs summary" summary)
71 writeDiff oldDocs newDocs
73 CodeVsExactly version ->
74 do (summary, name, vsns) <- getPackageInfo
75 oldDocs <- getDocs name vsns version
76 newDocs <- Task.silently (error "TODO Project.generateDocs summary" summary)
77 writeDiff oldDocs newDocs
80throw :: E.Exit -> Task.Task a
82 Task.throw $ Exit.Diff exit
89getDocs :: Pkg.Name -> [V.Version] -> V.Version -> Task.Task Docs.Documentation
90getDocs name allVersions version =
91 if elem version allVersions then
92 Cache.getDocs name version
94 throw $ E.UnknownVersion name version allVersions
97getPackageInfo :: Task.Task (Summary.Summary, Pkg.Name, [V.Version])
99 do summary <- Project.getRoot
100 case Summary._project summary of
102 throw $ E.Application
104 Project.Pkg (Project.PkgInfo name _ _ _ _ _ _ _) ->
105 do registry <- Cache.mandatoryUpdate
106 case Cache.getVersions name registry of
108 return ( summary, name, vsns )
118writeDiff :: Docs.Documentation -> Docs.Documentation -> Task.Task ()
119writeDiff oldDocs newDocs =
121 changes = Diff.diff oldDocs newDocs
122 localizer = L.fromNames (Map.union oldDocs newDocs)
124 liftIO $ Help.toStdout (toDoc localizer changes <> "\n")
131toDoc :: L.Localizer -> PackageChanges -> D.Doc
132toDoc localizer changes@(PackageChanges added changed removed) =
133 if null added && Map.null changed && null removed then
134 "No API changes detected, so this is a" <+> D.green "PATCH" <+> "change."
138 D.fromChars (Diff.magnitudeToString (Diff.toMagnitude changes))
141 "This is a" <+> D.green magDoc <+> "change."
144 if null added then [] else
145 [ Chunk "ADDED MODULES" MINOR $
146 D.vcat $ map (D.fromUtf8 . ModuleName.nameToString) added
150 if null removed then [] else
151 [ Chunk "REMOVED MODULES" MAJOR $
152 D.vcat $ map (D.fromUtf8 . ModuleName.nameToString) removed
156 addedChunk ++ removedChunk ++ map (changesToChunk localizer) (Map.toList changed)
158 D.vcat (header : "" : map chunkToDoc chunks)
164 , _magnitude :: Magnitude
169chunkToDoc :: Chunk -> D.Doc
170chunkToDoc (Chunk title magnitude details) =
173 Diff.magnitudeToString magnitude
176 "----" <+> D.fromChars title <+> "-" <+> D.fromChars magDoc <+> "----"
187changesToChunk :: L.Localizer -> (Name.Name, ModuleChanges) -> Chunk
188changesToChunk localizer (name, changes@(ModuleChanges unions aliases values binops)) =
191 Diff.moduleChangeMagnitude changes
193 (unionAdd, unionChange, unionRemove) =
194 changesToDocTriple (unionToDoc localizer) unions
196 (aliasAdd, aliasChange, aliasRemove) =
197 changesToDocTriple (aliasToDoc localizer) aliases
199 (valueAdd, valueChange, valueRemove) =
200 changesToDocTriple (valueToDoc localizer) values
202 (binopAdd, binopChange, binopRemove) =
203 changesToDocTriple (binopToDoc localizer) binops
205 Chunk (Name.toChars name) magnitude $
206 D.vcat $ List.intersperse "" $ Maybe.catMaybes $
207 [ changesToDoc "Added" unionAdd aliasAdd valueAdd binopAdd
208 , changesToDoc "Removed" unionRemove aliasRemove valueRemove binopRemove
209 , changesToDoc "Changed" unionChange aliasChange valueChange binopChange
213changesToDocTriple :: (k -> v -> D.Doc) -> Changes k v -> ([D.Doc], [D.Doc], [D.Doc])
214changesToDocTriple entryToDoc (Changes added changed removed) =
216 indented (name, value) =
217 D.indent 4 (entryToDoc name value)
219 diffed (name, (oldValue, newValue)) =
221 [ " - " <> entryToDoc name oldValue
222 , " + " <> entryToDoc name newValue
226 ( map indented (Map.toList added)
227 , map diffed (Map.toList changed)
228 , map indented (Map.toList removed)
232changesToDoc :: String -> [D.Doc] -> [D.Doc] -> [D.Doc] -> [D.Doc] -> Maybe D.Doc
233changesToDoc categoryName unions aliases values binops =
234 if null unions && null aliases && null values && null binops then
239 D.fromChars categoryName <> ":" : unions ++ aliases ++ binops ++ values
242unionToDoc :: L.Localizer -> Name.Name -> Docs.Union -> D.Doc
243unionToDoc localizer name (Docs.Union _ tvars ctors) =
246 "type" <+> D.fromName name <+> D.hsep (map D.fromName tvars)
248 ctorDoc (ctor, tipes) =
249 typeDoc localizer (Type.Type ctor tipes)
251 D.hang 4 (D.sep (setup : zipWith (<+>) ("=" : repeat "|") (map ctorDoc ctors)))
254aliasToDoc :: L.Localizer -> Name.Name -> Docs.Alias -> D.Doc
255aliasToDoc localizer name (Docs.Alias _ tvars tipe) =
258 "type" <+> "alias" <+> D.hsep (map D.fromName (name:tvars)) <+> "="
260 D.hang 4 (D.sep [ declaration, typeDoc localizer tipe ])
263valueToDoc :: L.Localizer -> Name.Name -> Docs.Value -> D.Doc
264valueToDoc localizer name (Docs.Value _ tipe) =
265 D.hang 4 $ D.sep [ D.fromName name <+> ":", typeDoc localizer tipe ]
268binopToDoc :: L.Localizer -> Name.Name -> Docs.Binop -> D.Doc
269binopToDoc localizer name (Docs.Binop _ tipe associativity (Docs.Precedence n)) =
270 "(" <> D.fromName name <> ")" <+> ":" <+> typeDoc localizer tipe <> D.black details
273 " (" <> D.fromName assoc <> "/" <> D.fromInt n <> ")"
276 case associativity of
279 Docs.Right -> "right"
282typeDoc :: L.Localizer -> Type.Type -> D.Doc
283typeDoc localizer tipe =
284 Type.toDoc localizer Type.None tipe
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