Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid pipes #106

Merged
merged 49 commits into from
Feb 9, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
72aed5c
Update for Elm 0.16
avh4 Oct 10, 2015
a2a1b51
Temporary workaround for elm-package 0.16.0-alpha2 creating invalid e…
avh4 Oct 10, 2015
2cfd4ce
Switch back to deadfoxygrandpa/elm-test
avh4 Oct 17, 2015
60344fa
Upgrade lodash
Oct 17, 2015
b3e899b
Upgrade to node-elm-compiler 1.0.0
Oct 17, 2015
30c1141
Use variable instead of two constants.
Oct 17, 2015
fdcc8ab
Use mkdir -p
Oct 17, 2015
0977137
Relax version bounds so both 0.15 and 0.16 theoretically work.
Oct 17, 2015
cc834f7
Merge pull request #10 from rtfeldman/upgrade-compiler
Oct 17, 2015
4640e31
node 0.10 should be fine.
Oct 17, 2015
9b8b8b0
Bump version number
Oct 17, 2015
1a7172e
Upgrade to node-elm-compiler 1.0.1
Oct 18, 2015
abc8386
Bump version number.
Oct 18, 2015
e4b20ba
Re-fix the Date bug originally fixed by 603c535c01beeb912c2057da05e17…
Oct 18, 2015
3a14dd9
Bump version number.
Oct 18, 2015
055da3a
Use correct elm-io-ports for the 0.15 version of elm-console
Oct 18, 2015
dfaa13a
Bump version number.
Oct 18, 2015
b20f4ef
Fix CI after removing dependency on npm Elm binaries
avh4 Oct 17, 2015
5708ed2
Don't build elm-reactor and elm-repl on CI
avh4 Oct 17, 2015
e37316e
Use deadfoxygrandpa/Elm-Test for Elm 0.15
avh4 Oct 17, 2015
12a7a88
Make CI test suite more robust against broken compilations
avh4 Oct 17, 2015
3d6aa32
Make elm-test init tests more robust against broken compilations
avh4 Oct 17, 2015
1a14af7
Run passing tests first on CI
avh4 Oct 17, 2015
82f660c
Revert to laszlopandy/elm-console/1.0.1 API for Elm 0.15
avh4 Oct 18, 2015
b690720
Go back to previous io script
Oct 18, 2015
37f09ad
Revert to 0.15-compatible libraries
Oct 18, 2015
712d606
Update some imports
Oct 18, 2015
daddbfd
Fix dependencies on example
Oct 18, 2015
add4702
Bump version number.
Oct 18, 2015
b8ce7d3
Merge remote-tracking branch 'rtfeldman/master' into fix-ci
avh4 Oct 19, 2015
997d000
Merge pull request #11 from avh4/fix-ci
Oct 21, 2015
c97919e
Bump version for 0.15 fix.
Oct 21, 2015
854550d
Do a Matrix build on Travis and run ci.sh
Nov 19, 2015
c7a8393
Bump minimum acceptable Node version from 0.10 to 0.12
Nov 19, 2015
59c1dcb
Allow elm-test prior to version 4.0.0
Nov 20, 2015
40bb15a
Update examples to use elm-test 3.0.0 API
Nov 20, 2015
4fc14d7
Bump package.json version to 0.16.0-beta
Nov 20, 2015
8e3e830
Add --version
Nov 20, 2015
f53826f
Add a test for --version
Nov 20, 2015
385b0a0
Merge pull request #17 from rtfeldman/0.16
Nov 20, 2015
8be7b06
Remove a console.log
Nov 22, 2015
c718c9e
Upgrade temp and fs-extra
Nov 22, 2015
ece680b
Add a --compiler flag
Nov 22, 2015
e1b054c
Strip out more unnecessary compiler output.
Nov 22, 2015
a5dc16b
Upgrade to node-elm-compiler 2.0.0
Nov 22, 2015
cfe012e
Merge pull request #20 from rtfeldman/compiler-flag
Nov 22, 2015
4464502
Bump version to beta2
Nov 22, 2015
d7bc645
Bump version to 0.16.0
Nov 22, 2015
959fda0
avoid piping in data via stdin to avoid stderr redirection bug in nod…
michaelglass Feb 9, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
language: node_js
node_js:
- "0.12"
sudo: false

env:
matrix:
- ELM_VERSION=0.16.0 TARGET_NODE_VERSION=node
- ELM_VERSION=0.16.0 TARGET_NODE_VERSION=0.12

install:
- nvm install $TARGET_NODE_VERSION
- nvm use $TARGET_NODE_VERSION
- node --version
- npm --version
- npm install -g elm@$ELM_VERSION

script: ./ci.sh
164 changes: 164 additions & 0 deletions BuildFromSource.hs
Original file line number Diff line number Diff line change
@@ -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"
71 changes: 46 additions & 25 deletions bin/elm-test
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var processTitle = "elm-test"

process.title = 'elm-test';
process.title = processTitle;

var compile = require("node-elm-compiler").compile,
suffix = require("../elm-io-ports.js"),
Expand All @@ -12,7 +12,16 @@ var compile = require("node-elm-compiler").compile,
util = require("util"),
_ = require("lodash"),
childProcess = require("child_process"),
elm = require("elm");
findup = require("findup-sync");

var elm = {
'elm-package': 'elm-package'
};

if (process.argv[2] == "--version") {
console.log(require(path.join(__dirname, "..", "package.json")).version);
process.exit(0);
}

if (process.argv[2] == "init") {
var copyTemplate = function(templateName) {
Expand All @@ -33,15 +42,17 @@ if (process.argv[2] == "init") {
childProcess.execSync(elm["elm-package"] + " " + command + elmOptions, {stdio:[0,1,2]});
}

execElmPackageSync("install deadfoxygrandpa/Elm-Test");
execElmPackageSync("install maxsnew/IO");
copyTemplate("elm-package.json");
execElmPackageSync("install deadfoxygrandpa/elm-test");
execElmPackageSync("install laszlopandy/elm-console");
copyTemplate("TestRunner.elm");
copyTemplate("Tests.elm");
process.exit(0);
}

var testFile = process.argv[2],
cwd = __dirname;
var testFile = process.argv[2],
cwd = __dirname,
pathToMake = undefined;

function spawnCompiler(cmd, args, opts) {
var compilerOpts = _.defaults({stdio: ["inherit", "pipe", "inherit"]}, opts);
Expand All @@ -51,7 +62,7 @@ function spawnCompiler(cmd, args, opts) {

if (typeof testFile !== "string") {
console.log("Usage: elm-test init [--yes] # Create example tests\n");
console.log("Usage: elm-test TESTFILE # Run tests\n");
console.log("Usage: elm-test TESTFILE [--compiler /path/to/compiler] # Run tests\n");
process.exit(1);
}

Expand All @@ -60,18 +71,27 @@ if (!fs.existsSync(testFile)) {
process.exit(1);
}

temp.open('elm_test_', function(err, info) {
var dest = info.path;
var compileProcess = compile([testFile], {output: dest, spawn: spawnCompiler});
if (process.argv[3] == "--compiler" || process.argv[3] == "-c") {
pathToMake = process.argv[4];

console.log("Compiling", testFile);
if (!pathToMake) {
console.error("The --compiler option must be given a path to an elm-make executable.");
process.exit(1);
}
}

temp.open({ prefix:'elm_test_', suffix:'.js' }, function(err, info) {
var dest = info.path;
var compileProcess = compile( [testFile],
{output: dest, spawn: spawnCompiler, pathToMake: pathToMake});

compileProcess.stdout.setEncoding("utf8")
compileProcess.stdout.on("data", function(data) {
// Explicitly strip out the "Successfully generated" message.
// This avoids the nasty compiler output message for the temp file, e.g.
// "Successfully generated /var/folders/f2/afd9fg0acfg32/elm_test_3423940"
if ((typeof data === "string") && !data.match(/^Successfully generated /)) {
// Also strip out "Success! Compiled 1 module."
if ((typeof data === "string") && !/^Success/.test(data)) {
console.log(data);
}
});
Expand All @@ -83,23 +103,24 @@ temp.open('elm_test_', function(err, info) {

console.log("Successfully compiled", testFile);

var runnerOpts = {stdio: ["pipe", "inherit", "inherit"]};
var runnerProcess = childProcess.spawn("node", [], runnerOpts);

runnerProcess.on('exit', function (exitCode) {
process.exit(exitCode);
});
// append suffix to temp file
fs.appendFile(dest, suffix, function(err){
if (err) throw(err);

var reader = fs.createReadStream(dest);
console.log("Bootstrapped test script")

reader.on("end", function() {
runnerProcess.stdin.write(suffix);
// add node_modules to NODE_PATH so the temporary file can require
// local modules
var pathToNodeModules = findup("node_modules");
process.env.NODE_PATH = _.compact([process.env.NODE_PATH, pathToNodeModules]).join(':');

runnerProcess.stdin.end();
})
var runnerProcess = childProcess.spawn("node", [dest], {stdio: 'inherit'});

reader.pipe(runnerProcess.stdin);
runnerProcess.on('exit', function (exitCode) {
process.exit(exitCode);
});

console.log("Running tests...");
console.log("Running tests...");
});
});
});
49 changes: 33 additions & 16 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,48 @@

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: Verifying installed elm-test version..."
elm-test --version

echo "$0: Testing examples..."
cd examples
assertTestSuccess PassingTests.elm
assertTestFailure FailingTests.elm
cd ..

echo "$0: Testing elm-test init..."
mkdir tmp
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 " "
Expand Down
Loading