1{-# OPTIONS_GHC -Wall #-}
2{-# LANGUAGE OverloadedStrings #-}
7 , toString, toText, toUrl, toFilePath
9 , dummyName, kernel, core
10 , browser, virtualDom, html
11 , webgl, linearAlgebra
13 , initialVersion, dummyVersion
14 , bumpPatch, bumpMinor, bumpMajor
15 , filterLatest, majorAndMinor
16 , versionToString, versionToText, versionFromText
25import Control.Monad (liftM, liftM2, liftM3)
26import Data.Binary (Binary, get, getWord8, put, putWord8)
27import qualified Data.Char as Char
28import Data.Function (on)
29import qualified Data.List as List
30import Data.Monoid ((<>))
31import qualified Data.Text as Text
32import qualified Data.Text.Read as Text
33import qualified Data.Text.Lazy as B (toStrict)
34import qualified Data.Text.Lazy.Builder as B (singleton, toLazyText)
35import qualified Data.Text.Lazy.Builder.Int as B (decimal)
36import Data.Text (Text)
37import Data.Word (Word16)
38import System.FilePath ((</>))
39import qualified Json.Decode.Internals as Decode
40import qualified Json.Encode as Encode
58 , _version :: !Version
67isKernel :: Name -> Bool
68isKernel (Name user _) =
69 user == "elm-lang" || user == "elm-explorations"
72toString :: Name -> String
74 Text.unpack (toText name)
78toText (Name user project) =
79 user <> "/" <> project
82toUrl :: Name -> String
83toUrl (Name user project) =
84 Text.unpack user ++ "/" ++ Text.unpack project
87toFilePath :: Name -> FilePath
88toFilePath (Name user project) =
89 Text.unpack user </> Text.unpack project
92fromText :: Text -> Either String Name
94 case Text.splitOn "/" text of
95 [ user, project ] | not (Text.null user || Text.null project) ->
96 Name user <$> validateProjectName project
99 Left "A valid project name looks like `user/project`"
102validateProjectName :: Text -> Either String Text
103validateProjectName text =
104 if Text.isInfixOf "--" text then
105 Left "There is a double dash -- in your package name. It must be a single dash."
107 else if Text.isInfixOf "_" text then
108 Left "Underscores are not allowed in package names."
110 else if Text.isInfixOf "." text then
111 Left "Dots are not allowed in package names."
113 else if Text.any Char.isUpper text then
114 Left "Upper case characters are not allowed in package names."
116 else if not (Char.isLetter (Text.head text)) then
117 Left "Package names must start with a letter."
119 else if Text.isSuffixOf "-" text then
120 Left "Package names cannot end with a dash."
127-- COMMON PACKAGE NAMES
130{-# NOINLINE dummyName #-}
133 Name "user" "project"
136{-# NOINLINE kernel #-}
139 Name "elm-lang" "kernel"
145 Name "elm-lang" "core"
148{-# NOINLINE browser #-}
151 Name "elm-lang" "browser"
154{-# NOINLINE virtualDom #-}
157 Name "elm-lang" "virtual-dom"
163 Name "elm-lang" "html"
166{-# NOINLINE webgl #-}
169 Name "elm-community" "webgl"
172{-# NOINLINE linearAlgebra #-}
175 Name "elm-community" "linear-algebra"
184 { _major :: {-# UNPACK #-} !Word16
185 , _minor :: {-# UNPACK #-} !Word16
186 , _patch :: {-# UNPACK #-} !Word16
191initialVersion :: Version
195dummyVersion :: Version
200bumpPatch :: Version -> Version
201bumpPatch (Version major minor patch) =
202 Version major minor (patch + 1)
205bumpMinor :: Version -> Version
206bumpMinor (Version major minor _patch) =
207 Version major (minor + 1) 0
210bumpMajor :: Version -> Version
211bumpMajor (Version major _minor _patch) =
212 Version (major + 1) 0 0
219filterLatest :: (Ord a) => (Version -> a) -> [Version] -> [Version]
220filterLatest characteristic versions =
221 map last (List.groupBy ((==) `on` characteristic) (List.sort versions))
224majorAndMinor :: Version -> ( Int, Int )
225majorAndMinor (Version major minor _patch) =
226 ( fromIntegral major, fromIntegral minor )
233versionToString :: Version -> String
234versionToString version =
235 Text.unpack (versionToText version)
238versionToText :: Version -> Text
239versionToText (Version major minor patch) =
240 B.toStrict $ B.toLazyText $
248versionFromText :: Text -> Either String Version
249versionFromText text =
250 case Text.splitOn "." text of
251 [major, minor, patch] ->
258 Left "Must have format MAJOR.MINOR.PATCH (e.g. 1.0.2)"
261toNumber :: Text -> Either String Word16
263 case Text.decimal txt of
268 Left "Must have format MAJOR.MINOR.PATCH (e.g. 1.0.2)"
275instance Binary Name where
279 put (Name user project) =
284instance Binary Package where
286 liftM2 Package get get
288 put (Package name version) =
293instance Binary Version where
297 then liftM3 Version get get get
299 do minor <- liftM fromIntegral getWord8
300 patch <- liftM fromIntegral getWord8
301 return (Version (fromIntegral word) minor patch)
303 put (Version major minor patch) =
304 if major < 256 && minor < 256 && patch < 256 then
305 do putWord8 (fromIntegral major)
306 putWord8 (fromIntegral minor)
307 putWord8 (fromIntegral patch)
319decoder :: Decode.Decoder String Name
321 do txt <- Decode.text
330encode :: Name -> Encode.Value
332 Encode.text (toText name)
336versionDecoder :: Decode.Decoder String Version
338 do txt <- Decode.text
339 case versionFromText txt of
341 Decode.succeed version
347encodeVersion :: Version -> Encode.Value
348encodeVersion version =
349 Encode.text (versionToText version)
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