on master help sign in
Merge pull request #1032 from JoeyEremondi/commonPackageFile

Common package module (take 2)

commit803e56bb27a1236f426f539129718b6dce6dce78 authorEvan Czaplicki <info@elm-lang.org> dateThu 27 Aug 2015, 13:48 (11 years ago) parent053905f6285a63
10 files changed+234−32
elm-compiler.cabal+6 src/AST/Module.hs+2−1 src/CommandLineRouter.hs+2−2 src/Compile.hs+4−4 src/Elm/Compiler.hs+8−13 src/Elm/Compiler/Version.hs+17−6 src/Elm/Docs.hs+2−1 src/Elm/Package.hs+187 src/Elm/Utils.hs+4−3 tests/Test/Compiler.hs+2−2
elm-compiler.cabal+6
@@ -43,6 +43,7 @@ Library
4343 Elm.Compiler.Module,
4444 Elm.Compiler.Type,
4545 Elm.Docs,
46+ Elm.Package,
4647 Elm.Utils
4748
4849 other-modules:
@@ -165,7 +166,12 @@ Executable elm
165166
166167 Build-depends:
167168 base >=4.2 && <5,
169+ aeson >= 0.7 && < 0.9,
170+ binary >= 0.7.0.0 && < 0.8,
168171 directory >= 1.0 && < 2.0,
172+ filepath >= 1 && < 2.0,
173+ mtl >= 2.2 && < 3,
174+ text >= 1 && < 2,
169175 elm-compiler,
170176 process
171177
src/AST/Module.hs+2−1
@@ -21,6 +21,7 @@ import qualified AST.Expression.Optimized as Optimized
2121import qualified AST.Type as Type
2222import qualified AST.Variable as Var
2323import qualified Docs.AST as Docs
24+import qualified Elm.Package as Package
2425import qualified Elm.Compiler.Version as Compiler
2526import qualified Reporting.Annotation as A
2627
@@ -142,7 +143,7 @@ toInterface :: CanonicalModule -> Interface
142143toInterface modul =
143144 let body' = body modul in
144145 Interface
145− { iVersion = Compiler.version
146+ { iVersion = Package.versionToString Compiler.version
146147 , iExports = exports modul
147148 , iTypes = types body'
148149 , iImports = imports modul
src/CommandLineRouter.hs+2−2
@@ -7,7 +7,7 @@ import System.IO (hPutStrLn, stderr, stdin, stdout)
77import qualified System.Process as Proc
88
99import qualified Elm.Compiler.Version as Compiler
10−
10+import qualified Elm.Package as Pkg
1111
1212main :: IO ()
1313main =
@@ -47,7 +47,7 @@ attemptToRun command args =
4747
4848usageMessage :: String
4949usageMessage =
50− "Elm Platform " ++ Compiler.version ++ " - a way to run all Elm tools\n\
50+ "Elm Platform " ++ (Pkg.versionToString Compiler.version) ++ " - a way to run all Elm tools\n\
5151 \\n\
5252 \Usage: elm <command> [<args>]\n\
5353 \\n\
src/Compile.hs+4−4
@@ -5,6 +5,7 @@ import qualified Data.Map as Map
55import qualified AST.Module as Module
66import qualified Canonicalize
77import Elm.Utils ((|>))
8+import qualified Elm.Package as Package
89import qualified Nitpick.PatternMatches as Nitpick
910import qualified Nitpick.TopLevelTypes as Nitpick
1011import qualified Parse.Helpers as Parse
@@ -16,19 +17,18 @@ import qualified Type.Inference as TI
1617
1718
1819compile
19− :: String
20− -> String
20+ :: Package.Name
2121 -> Bool
2222 -> Module.Interfaces
2323 -> String
2424 -> Result.Result Warning.Warning Error.Error Module.CanonicalModule
2525
26−compile user projectName isRoot interfaces source =
26+compile packageName isRoot interfaces source =
2727 do
2828 -- determine if default imports should be added
2929 -- only elm-lang/core is exempt
3030 let needsDefaults =
31− not (user == "elm-lang" && projectName == "core")
31+ not (packageName == Package.coreName)
3232
3333 -- Parse the source code
3434 validModule <-
src/Elm/Compiler.hs+8−13
@@ -1,6 +1,6 @@
11{-# OPTIONS_GHC -Wall #-}
22module Elm.Compiler
3− ( version, rawVersion
3+ ( version
44 , parseDependencies
55 , compile, Context(..), Result(..)
66 , Dealiaser, dummyDealiaser
@@ -14,9 +14,10 @@ import qualified Data.Map as Map
1414import qualified AST.Module as Module
1515import qualified Compile
1616import qualified Docs.Check as Docs
17+import qualified Elm.Compiler.Version
1718import qualified Elm.Compiler.Module as PublicModule
18−import qualified Elm.Compiler.Version as Version
1919import qualified Elm.Docs as Docs
20+import qualified Elm.Package as Package
2021import qualified Generate.JavaScript as JS
2122import qualified Optimize
2223import qualified Parse.Module as Parse
@@ -30,14 +31,9 @@ import qualified Reporting.Warning as Warning
3031
3132-- VERSION
3233
33−version :: String
34+version :: Package.Version
3435version =
35− Version.version
36−
37−
38−rawVersion :: [Int]
39−rawVersion =
40− Version.rawVersion
36+ Elm.Compiler.Version.version
4137
4238
4339-- DEPENDENCIES
@@ -72,14 +68,14 @@ compile
7268
7369compile context source interfaces =
7470 let
75− (Context user packageName isRoot isExposed) =
71+ (Context packageName isRoot isExposed) =
7672 context
7773
7874 unwrappedInterfaces =
7975 Map.mapKeysMonotonic (\(PublicModule.Name name) -> name) interfaces
8076
8177 (Result.Result (dealiaser, warnings) rawResult) =
82− do modul <- Compile.compile user packageName isRoot unwrappedInterfaces source
78+ do modul <- Compile.compile packageName isRoot unwrappedInterfaces source
8379 docs <- docsGen isExposed modul
8480
8581 let interface = Module.toInterface modul
@@ -95,8 +91,7 @@ compile context source interfaces =
9591
9692
9793data Context = Context
98− { _user :: String
99− , _packageName :: String
94+ { _packageName :: Package.Name
10095 , _isRoot :: Bool
10196 , _isExposed :: Bool
10297 }
src/Elm/Compiler/Version.hs+17−6
@@ -1,15 +1,26 @@
11{-# OPTIONS_GHC -Wall #-}
2−module Elm.Compiler.Version (version, rawVersion) where
2+module Elm.Compiler.Version (version) where
33
44import qualified Data.Version as Version
55import qualified Paths_elm_compiler as This
6+import Elm.Package
67
78
8−version :: String
9+rawVersion :: [Int]
10+rawVersion =
11+ Version.versionBranch This.version
12+
13+version :: Version
914version =
10− Version.showVersion This.version
15+ case rawVersion of
16+ major : minor : patch : _ ->
17+ Version major minor patch
1118
19+ [major, minor] ->
20+ Version major minor 0
1221
13−rawVersion :: [Int]
14−rawVersion =
15− Version.versionBranch This.version
22+ [major] ->
23+ Version major 0 0
24+
25+ [] ->
26+ error "could not detect version of elm-compiler you are using"
src/Elm/Docs.hs+2−1
@@ -14,6 +14,7 @@ import qualified Docs.AST as Docs
1414import qualified Elm.Compiler.Module as Module
1515import qualified Elm.Compiler.Type as Type
1616import qualified Elm.Compiler.Version as Version
17+import qualified Elm.Package as Pkg
1718import qualified Reporting.Annotation as A
1819
1920
@@ -75,7 +76,7 @@ fromCheckedDocs name (Docs.Docs comment aliases unions values) =
7576 (map toAlias (Map.toList aliases))
7677 (map toUnion (Map.toList unions))
7778 (map toValue (Map.toList values))
78− (Version Version.version)
79+ (Version $ (Pkg.versionToString Version.version))
7980
8081
8182-- PRETTY JSON
src/Elm/Package.hsnew file+187
@@ -0,0 +1,187 @@
1+{-# LANGUAGE FlexibleContexts #-}
2+module Elm.Package where
3+
4+import Control.Applicative ((<$>), (<*>))
5+import Control.Monad.Error.Class (MonadError, throwError)
6+import Data.Aeson
7+import Data.Binary
8+import qualified Data.List as List
9+import qualified Data.Text as T
10+import qualified Data.Maybe as Maybe
11+import System.FilePath ((</>))
12+import Data.Char (isDigit)
13+import Data.Function (on)
14+
15+data Name = Name
16+ { user :: String
17+ , project :: String
18+ }
19+ deriving (Eq, Ord)
20+
21+
22+dummyName :: Name
23+dummyName =
24+ Name "USER" "PROJECT"
25+
26+
27+coreName :: Name
28+coreName =
29+ Name "elm-lang" "core"
30+
31+
32+toString :: Name -> String
33+toString name =
34+ user name ++ "/" ++ project name
35+
36+
37+toUrl :: Name -> String
38+toUrl name =
39+ user name ++ "/" ++ project name
40+
41+
42+toFilePath :: Name -> FilePath
43+toFilePath name =
44+ user name </> project name
45+
46+
47+fromString :: String -> Maybe Name
48+fromString string =
49+ case break (=='/') string of
50+ ( user@(_:_), '/' : project@(_:_) )
51+ | all (/='/') project -> Just (Name user project)
52+ _ -> Nothing
53+
54+
55+fromString' :: (MonadError String m) => String -> m Name
56+fromString' string =
57+ Maybe.maybe (throwError $ errorMsg string) return (fromString string)
58+
59+
60+instance Binary Name where
61+ get = Name <$> get <*> get
62+ put (Name user project) =
63+ do put user
64+ put project
65+
66+
67+instance FromJSON Name where
68+ parseJSON (String text) =
69+ let string = T.unpack text in
70+ Maybe.maybe (fail $ errorMsg string) return (fromString string)
71+
72+ parseJSON _ = fail "Project name must be a string."
73+
74+
75+instance ToJSON Name where
76+ toJSON name =
77+ toJSON (toString name)
78+
79+
80+errorMsg :: String -> String
81+errorMsg string =
82+ unlines
83+ [ "Dependency file has an invalid name: " ++ string
84+ , "Must have format USER/PROJECT and match a public github project."
85+ ]
86+
87+
88+
89+
90+data Version = Version
91+ { major :: Int
92+ , minor :: Int
93+ , patch :: Int
94+ }
95+ deriving (Eq, Ord)
96+
97+
98+initialVersion :: Version
99+initialVersion =
100+ Version 1 0 0
101+
102+dummyVersion :: Version
103+dummyVersion =
104+ Version 0 0 0
105+
106+
107+bumpPatch :: Version -> Version
108+bumpPatch (Version major minor patch) =
109+ Version major minor (patch + 1)
110+
111+bumpMinor :: Version -> Version
112+bumpMinor (Version major minor _patch) =
113+ Version major (minor + 1) 0
114+
115+bumpMajor :: Version -> Version
116+bumpMajor (Version major _minor _patch) =
117+ Version (major + 1) 0 0
118+
119+
120+-- FILTERING
121+
122+filterLatest :: (Ord a) => (Version -> a) -> [Version] -> [Version]
123+filterLatest characteristic versions =
124+ map last (List.groupBy ((==) `on` characteristic) (List.sort versions))
125+
126+
127+majorAndMinor :: Version -> (Int,Int)
128+majorAndMinor (Version major minor _patch) =
129+ (major, minor)
130+
131+
132+-- CONVERSIONS
133+
134+versionToString :: Version -> String
135+versionToString (Version major minor patch) =
136+ show major ++ "." ++ show minor ++ "." ++ show patch
137+
138+
139+versionFromString :: String -> Maybe Version
140+versionFromString string =
141+ case splitNumbers string of
142+ Just [major, minor, patch] ->
143+ Just (Version major minor patch)
144+ _ -> Nothing
145+ where
146+ splitNumbers :: String -> Maybe [Int]
147+ splitNumbers ns =
148+ case span isDigit ns of
149+ ("", _) ->
150+ Nothing
151+
152+ (numbers, []) ->
153+ Just [ read numbers ]
154+
155+ (numbers, '.':rest) ->
156+ (read numbers :) <$> splitNumbers rest
157+
158+ _ -> Nothing
159+
160+
161+instance Binary Version where
162+ get = Version <$> get <*> get <*> get
163+ put (Version major minor patch) =
164+ do put major
165+ put minor
166+ put patch
167+
168+
169+instance FromJSON Version where
170+ parseJSON (String text) =
171+ let string = T.unpack text in
172+ case versionFromString string of
173+ Just v -> return v
174+ Nothing ->
175+ fail $ unlines
176+ [ "Dependency file has an invalid version number: " ++ string
177+ , "Must have format MAJOR.MINOR.PATCH (e.g. 0.1.2)"
178+ ]
179+
180+ parseJSON _ =
181+ fail "Version number must be stored as a string."
182+
183+
184+instance ToJSON Version where
185+ toJSON version =
186+ toJSON (versionToString version)
187+
src/Elm/Utils.hs+4−3
@@ -20,6 +20,7 @@ import System.Process (readProcessWithExitCode)
2020import qualified AST.Expression.Source as Source
2121import qualified AST.Pattern as Pattern
2222import qualified Elm.Compiler.Version as Version
23+import qualified Elm.Package as Pkg
2324import qualified Parse.Helpers as Parse
2425import qualified Parse.Expression as Parse
2526import qualified Reporting.Annotation as A
@@ -127,8 +128,8 @@ errorNotFound name =
127128 , ""
128129 , " * On Mac it is /usr/local/share/elm"
129130 , " * On Windows it is one of the following:"
130− , " C:/Program Files/Elm Platform/" ++ Version.version ++ "/share"
131− , " C:/Program Files (x86)/Elm Platform/" ++ Version.version ++ "/share"
131+ , " C:/Program Files/Elm Platform/" ++ (Pkg.versionToString Version.version) ++ "/share"
132+ , " C:/Program Files (x86)/Elm Platform/" ++ (Pkg.versionToString Version.version) ++ "/share"
132133 , ""
133134 , "If you installed using npm, you have to set ELM_HOME to a certain directory"
134135 , "of the form .../node_modules/elm/share"
@@ -147,4 +148,4 @@ isDeclaration string =
147148 Just (List.intercalate "$" (Pattern.boundVarList pattern))
148149
149150 _ ->
150− Nothing
151+ Nothing
tests/Test/Compiler.hs+2−2
@@ -12,7 +12,7 @@ import Test.Framework.Providers.HUnit (testCase)
1212import Test.HUnit (Assertion, assertFailure, assertBool)
1313
1414import qualified Elm.Compiler as Compiler
15−
15+import qualified Elm.Package as Package
1616
1717compilerTests :: Test
1818compilerTests =
@@ -54,7 +54,7 @@ testIf handleResult filePaths =
5454 source <- readFile filePath
5555
5656 let context =
57− Compiler.Context "elm-lang" "core" True False
57+ Compiler.Context (Package.Name "elm-lang" "core") True False
5858 let (dealiaser, _warnings, result) =
5959 Compiler.compile context source Map.empty
6060 let formatErrors errors =