diff --git a/.travis.yml b/.travis.yml index 796d98f9..b4c55596 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,19 @@ +sudo: false + language: node_js node_js: - "0.12" + +addons: + apt: + sources: + - hvr-ghc + packages: + - cabal-install-1.22 + - ghc-7.10.1 + + +before_install: + - export PATH=/opt/ghc/7.10.1/bin:/opt/cabal/1.22/bin:./Elm-Platform/0.15.1/.cabal-sandbox/bin:$PATH + - runhaskell BuildFromSource.hs 0.15.1 + - export PATH="`pwd`"/Elm-Platform/0.15.1/.cabal-sandbox/bin:$PATH diff --git a/BuildFromSource.hs b/BuildFromSource.hs new file mode 100644 index 00000000..719741ba --- /dev/null +++ b/BuildFromSource.hs @@ -0,0 +1,164 @@ +{-| This script builds any version of the Elm Platform from source. +Before you use it, make sure you have the Haskell Platform with a recent +version of cabal. + +To install a released version of Elm, you will run something like this: + + runhaskell BuildFromSource.hs 0.15.1 + +Before you do that, in some directory of your choosing, add +wherever/Elm-Platform/0.15.1/.cabal-sandbox/bin to your PATH. + +Then, run the above. You will now actually have a new directory for the +Elm Platform, like this: + + Elm-Platform/0.15.1/ + elm-make/ -- git repo for the build tool, ready to edit + elm-repl/ -- git repo for the REPL, ready to edit + ... + .cabal-sandbox/ -- various build files + +All of the executables you need are in .cabal-sandbox/bin, which is on +your PATH and thus can be used from anywhere. + +You can build many versions of the Elm Platform, so it is possible to have +Elm-Platform/0.15.1/ and Elm-Platform/0.13/ with no problems. It is up to you +to manage your PATH variable or symlinks though. + +To get set up with the master branch of all Elm Platform projects, run this: + + runhaskell BuildFromSource.hs master + +From there you can start developing on any of the projects, switching branches +and testing interactions between projects. +-} +module Main where + +import qualified Data.List as List +import qualified Data.Map as Map +import System.Directory (createDirectoryIfMissing, + getCurrentDirectory, setCurrentDirectory) +import System.Environment (getArgs) +import System.Exit (ExitCode, exitFailure) +import System.FilePath (()) +import System.IO (hPutStrLn, stderr) +import System.Process (rawSystem) + + +(=:) = (,) + +configs :: Map.Map String [(String, String)] +configs = + Map.fromList + [ + "master" =: + [ "elm-compiler" =: "master" + , "elm-package" =: "master" + , "elm-make" =: "master" + , "elm-reactor" =: "master" + , "elm-repl" =: "master" + ] + , + "0.15.1" =: + [ "elm-compiler" =: "0.15.1" + , "elm-package" =: "0.5.1" + , "elm-make" =: "0.2" + ] + , + "0.15" =: + [ "elm-compiler" =: "0.15" + , "elm-package" =: "0.5" + , "elm-make" =: "0.1.2" + , "elm-reactor" =: "0.3.1" + , "elm-repl" =: "0.4.1" + ] + , + "0.14.1" =: + [ "elm-compiler" =: "0.14.1" + , "elm-package" =: "0.4" + , "elm-make" =: "0.1.1" + , "elm-reactor" =: "0.3" + , "elm-repl" =: "0.4" + ] + , + "0.14" =: + [ "elm-compiler" =: "0.14" + , "elm-package" =: "0.2" + , "elm-make" =: "0.1" + , "elm-reactor" =: "0.2" + , "elm-repl" =: "0.4" + ] + , + "0.13" =: + [ "Elm" =: "0.13" + , "elm-reactor" =: "0.1" + , "elm-repl" =: "0.3" + , "elm-get" =: "0.1.3" + ] + , + "0.12.3" =: + [ "Elm" =: "0.12.3" + , "elm-server" =: "0.11.0.1" + , "elm-repl" =: "0.2.2.1" + , "elm-get" =: "0.1.2" + ] + ] + + +main :: IO () +main = + do args <- getArgs + case args of + [version] | Map.member version configs -> + let artifactDirectory = "Elm-Platform" version + repos = configs Map.! version + in + makeRepos artifactDirectory version repos + + _ -> + do hPutStrLn stderr $ + "Expecting one of the following values as an argument:\n" ++ + " " ++ List.intercalate ", " (Map.keys configs) + exitFailure + + +makeRepos :: FilePath -> String -> [(String, String)] -> IO () +makeRepos artifactDirectory version repos = + do createDirectoryIfMissing True artifactDirectory + setCurrentDirectory artifactDirectory + root <- getCurrentDirectory + mapM_ (uncurry (makeRepo root)) repos + + cabal [ "update" ] + + -- create a sandbox for installation + cabal [ "sandbox", "init" ] + + -- add each of the sub-directories as a sandbox source + cabal ([ "sandbox", "add-source" ] ++ map fst repos) + + -- install all of the packages together in order to resolve transitive dependencies robustly + -- (install the dependencies a bit more quietly than the elm packages) + cabal ([ "install", "-j", "--only-dependencies", "--ghc-options=\"-w\"" ] ++ (if version <= "0.15.1" then [ "--constraint=fsnotify<0.2" ] else []) ++ map fst repos) + cabal ([ "install", "-j", "--ghc-options=\"-XFlexibleContexts\"" ] ++ filter (/= "elm-reactor") (map fst repos)) + + return () + +makeRepo :: FilePath -> String -> String -> IO () +makeRepo root projectName version = + do -- get the right version of the repo + git [ "clone", "https://github.com/elm-lang/" ++ projectName ++ ".git" ] + setCurrentDirectory projectName + git [ "checkout", version, "--quiet" ] + + -- move back into the root + setCurrentDirectory root + + +-- HELPER FUNCTIONS + +cabal :: [String] -> IO ExitCode +cabal = rawSystem "cabal" + +git :: [String] -> IO ExitCode +git = rawSystem "git" diff --git a/ci.sh b/ci.sh index e25b223c..347c3e8b 100755 --- a/ci.sh +++ b/ci.sh @@ -2,31 +2,45 @@ set -e +function assertTestFailure() { + elm-package install --yes + elm-test "$1" | tee "$1".test.log + if test ${PIPESTATUS[0]} -ne 1; then + echo "$0: ERROR: $1: Expected tests to fail" >&2 + exit 1 + fi +} + +function assertTestSuccess() { + elm-package install --yes + elm-test "$1" | tee "$1".test.log + if test ${PIPESTATUS[0]} -ne 0; then + echo "$0: ERROR: $1: Expected tests to pass" >&2 + exit 1 + fi +} + echo "$0: Installing elm-test..." npm install --global +echo "$0: Testing examples..." +cd examples +assertTestSuccess PassingTests.elm +assertTestFailure FailingTests.elm +cd .. + echo "$0: Testing elm-test init..." mkdir -p tmp cd tmp elm-test init --yes -elm-test TestRunner.elm | tee test.log -if test ${PIPESTATUS[0]} -ne 1; then - echo "$0: ERROR: Expected example tests to fail" >&2 - exit 1 -fi +assertTestFailure TestRunner.elm +# delete the failing tests and the comma on the preceding line +ex -c 'g/should fail/' -c 'd' -c 'g-1' -c 's/,$//' -c 'wq' Tests.elm +rm -Rf elm-stuff +assertTestSuccess TestRunner.elm cd .. rm -Rf tmp -echo "$0: Testing examples..." -cd examples -elm-package install --yes -elm-test Test.elm | tee test.log -if test ${PIPESTATUS[0]} -ne 1; then - echo "$0: ERROR: Expected example tests to fail" >&2 - exit 1 -fi -cd .. - echo "" echo "$0: Everything looks good!" echo " " diff --git a/elm-io-ports.js b/elm-io-ports.js index 1d662255..bc0c3682 100644 --- a/elm-io-ports.js +++ b/elm-io-ports.js @@ -1,45 +1,8 @@ -/* Implementation from: https://raw.githubusercontent.com/maxsnew/IO/master/elm-io.sh */ +/* Implementation from: https://github.com/laszlopandy/elm-console/blob/master/elm-io.sh */ module.exports = "(function(){\n" + " window = {Date: Date};\n" + - " var stdin = process.stdin;\n" + - " var fs = require('fs');\n" + - " var worker = Elm.worker(Elm.Main, {responses: null });\n" + - " var just = function(v) {\n" + - " return { 'Just': v};\n" + - " }\n" + - " var handle = function(request) {\n" + - " switch(request.ctor) {\n" + - " case 'Put':\n" + - " process.stdout.write(request.val);\n" + - " break;\n" + - " case 'Get':\n" + - " stdin.resume();\n" + - " break;\n" + - " case 'Exit':\n" + - " process.exit(request.val);\n" + - " break;\n" + - " case 'WriteFile':\n" + - " fs.writeFileSync(request.file, request.content);\n" + - " break;\n" + - " }\n" + - " }\n" + - " var handler = function(reqs) {\n" + - " for (var i = 0; i < reqs.length; i++) {\n" + - " handle(reqs[i]);\n" + - " }\n" + - " if (reqs.length > 0 && reqs[reqs.length - 1].ctor !== 'Get') {\n" + - " worker.ports.responses.send(just(\"\"));\n" + - " }\n" + - " }\n" + - " worker.ports.requests.subscribe(handler);\n" + - " \n" + - " // Read\n" + - " stdin.on('data', function(chunk) {\n" + - " stdin.pause();\n" + - " worker.ports.responses.send(just(chunk.toString()));\n" + - " })\n" + - "\n" + - " // Start msg\n" + - " worker.ports.responses.send(null);\n" + + " if (typeof Elm === \"undefined\") { throw \"elm-io config error: Elm is not defined. Make sure you call elm-io with a real Elm output file\"}\n" + + " if (typeof Elm.Main === \"undefined\" ) { throw \"Elm.Main is not defined, make sure your module is named Main.\" };\n" + + " var worker = Elm.worker(Elm.Main);\n" + "})();\n"; diff --git a/examples/Test.elm b/examples/FailingTests.elm similarity index 72% rename from examples/Test.elm rename to examples/FailingTests.elm index 7794a0d7..ea1eb7b7 100644 --- a/examples/Test.elm +++ b/examples/FailingTests.elm @@ -7,10 +7,8 @@ import ElmTest.Assertion as A exposing (assertEqual, assert) import ElmTest.Run as R import ElmTest.Runner.Console exposing (runDisplay) import ElmTest.Test exposing (..) -import IO.IO exposing (..) -import IO.Runner exposing (Request, Response) -import IO.Runner as Run - +import Console exposing (IO, run) +import Task import String tests : Test @@ -23,7 +21,5 @@ tests = suite "A Test Suite" console : IO () console = runDisplay tests -port requests : Signal Request -port requests = Run.run responses console - -port responses : Signal Response +port runner : Signal (Task.Task x ()) +port runner = run console diff --git a/examples/PassingTests.elm b/examples/PassingTests.elm new file mode 100644 index 00000000..4d296ebc --- /dev/null +++ b/examples/PassingTests.elm @@ -0,0 +1,24 @@ +module Main where + +import Basics exposing (..) +import Signal exposing (..) + +import ElmTest.Assertion as A exposing (assertEqual, assert) +import ElmTest.Run as R +import ElmTest.Runner.Console exposing (runDisplay) +import ElmTest.Test exposing (..) +import Console exposing (IO, run) +import Task +import String + +tests : Test +tests = suite "A Test Suite" + [ test "Addition" (assertEqual (3 + 7) 10) + , test "String.left" (assertEqual "a" (String.left 1 "abcdefg")) + ] + +console : IO () +console = runDisplay tests + +port runner : Signal (Task.Task x ()) +port runner = run console diff --git a/examples/elm-package.json b/examples/elm-package.json index 23e7eca0..2f8cc1bd 100644 --- a/examples/elm-package.json +++ b/examples/elm-package.json @@ -8,9 +8,9 @@ ], "exposed-modules": [], "dependencies": { - "elm-lang/core": "2.0.0 <= v < 3.0.0", - "deadfoxygrandpa/Elm-Test": "1.0.4 <= v <= 1.0.4", - "maxsnew/IO": "1.0.1 <= v <= 1.0.1" + "deadfoxygrandpa/elm-test": "2.0.0 <= v < 3.0.0", + "elm-lang/core": "2.0.0 <= v < 4.0.0", + "laszlopandy/elm-console": "1.0.1 <= v < 2.0.0" }, - "elm-version": "0.15.0 <= v < 0.16.0" + "elm-version": "0.15.0 <= v < 0.17.0" } diff --git a/templates/TestRunner.elm b/templates/TestRunner.elm index b5109ee7..35f5be45 100644 --- a/templates/TestRunner.elm +++ b/templates/TestRunner.elm @@ -3,16 +3,13 @@ module Main where import Signal exposing (Signal) import ElmTest.Runner.Console exposing (runDisplay) -import IO.IO exposing (IO) -import IO.Runner exposing (Request, Response) -import IO.Runner as Run +import Console exposing (IO, run) +import Task import Tests console : IO () console = runDisplay Tests.all -port requests : Signal Request -port requests = Run.run responses console - -port responses : Signal Response +port runner : Signal (Task.Task x ()) +port runner = run console diff --git a/templates/elm-package.json b/templates/elm-package.json index 7eff4ab8..4053c0e7 100644 --- a/templates/elm-package.json +++ b/templates/elm-package.json @@ -8,7 +8,7 @@ ], "exposed-modules": [], "dependencies": { - "elm-lang/core": "3.0.0 <= v < 4.0.0" + "elm-lang/core": "2.0.0 <= v < 4.0.0" }, - "elm-version": "0.16.0 <= v < 0.17.0" + "elm-version": "0.15.0 <= v < 0.17.0" }