Skip to content

Commit

Permalink
Merge pull request #934 from rtfeldman/add-elm
Browse files Browse the repository at this point in the history
Add Elm language support
  • Loading branch information
BanzaiMan committed Nov 20, 2018
2 parents 149ff67 + e386ff2 commit 24db35b
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 0 deletions.
1 change: 1 addition & 0 deletions lib/travis/build/addons/deploy/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Script
VERSIONED_RUNTIMES = %i(
d
dart
elm
elixir
ghc
go
Expand Down
1 change: 1 addition & 0 deletions lib/travis/build/script.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
require 'travis/build/script/julia'
require 'travis/build/script/nix'
require 'travis/build/script/node_js'
require 'travis/build/script/elm'
require 'travis/build/script/objective_c'
require 'travis/build/script/perl'
require 'travis/build/script/perl6'
Expand Down
191 changes: 191 additions & 0 deletions lib/travis/build/script/elm.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
module Travis
module Build
class Script
class Elm < NodeJs
# Default NodeJS version to install
DEFAULT_NODE_VERSION = '10.13.0'

DEFAULTS = {
elm: 'elm0.19.0',
elm_test: 'elm0.19.0',
elm_format: 'elm0.19.0'
}

ELM_TEST_REQUIRED_NODE_VERSION = '6.0.0'

def export
super
sh.export 'TRAVIS_ELM_VERSION', elm_version, echo: false
sh.export 'TRAVIS_ELM_TEST_VERSION', elm_test_version, echo: false
sh.export 'TRAVIS_ELM_FORMAT_VERSION', elm_format_version, echo: false
end

def configure
super

config[:node_js] ||= DEFAULT_NODE_VERSION
end

def announce
super
sh.cmd 'elm --version', echo: true
sh.cmd 'elm-test --version', echo: true

# elm-format doesn't have --version,
# but the first line of `elm-format --help` prints the version
sh.cmd 'elm-format --help | head -n 1', echo: true

sh.echo '' # A blank line visually separates this from the next cmd
end

def setup
super

sh.echo 'Elm for Travis-CI is not officially supported, ' \
'but is community maintained.', ansi: :green
sh.echo 'Please file any issues using the following link',
ansi: :green
sh.echo ' https://github.com/travis-ci/travis-ci/issues' \
'/new?labels=community:elm', ansi: :green
sh.echo 'and mention \`@avh4\`, \`@lukewestby\`, \`@stoeffel\` and \`@rtfeldman\`' \
' in the issue', ansi: :green


sh.if '! -d sysconfcpus/bin' do
install_sysconfcpus
end

sh.echo 'Installing elm, elm-test, and elm-format', ansi: :green
sh.fold 'install.elm' do
install_elm
install_elm_test
install_elm_format
end
end

def script
sh.cmd 'elm-format --validate . && elm-test'
end

def setup_cache
if data.cache?(:elm)
sh.fold 'cache.elm' do
# Cache the ~/.elm directory.
directory_cache.add '$HOME/.cache/elm', '$HOME/.elm'

directory_cache.add '$HOME/.cache/elm-stuff', 'elm-stuff'

if elm_major_version == 0 && elm_minor_version <= 18
# In Elm 0.18, some put their tests in ./test instead of ./tests
directory_cache.add '$HOME/.cache/elm-test-stuff', 'test/elm-stuff'
end

# In Elm 0.18+, all tests live in tests/ by default
# (whereas previously tests/ was allowed, but so was test/)
directory_cache.add '$HOME/.cache/elm-tests-stuff', 'tests/elm-stuff'

# we build sysconfcpus from source, so cache the result
directory_cache.add '$HOME/.cache/sysconfcpus-cache', 'sysconfcpus'
end
end
end

def cache_slug
super << '-elm-' << elm_version
end

private

def elm_version
config[:elm].to_s
end

def elm_version_number(index)
elm_version.gsub(/[a-zA-Z]/, "").split(".")[index]
end

def elm_major_version
elm_version_number 0
end

def elm_minor_version
elm_version_number 1
end

def elm_patch_version
elm_version_number 2
end

def elm_test_version
config[:elm_test].to_s
end

def elm_format_version
config[:elm_format].to_s
end

def npm_install_global(package_name, package_version)
sh.cmd "npm install -g #{package_name}@#{package_version}"
end

def install_elm
npm_install_global 'elm', elm_version

convert_binary_to_sysconfcpus 'elm'

# Beginning with Elm 0.19, there's one `elm` binary and that's it.
# In that case, there won't be any files to convert here!
if elm_major_version == 0 && elm_minor_version <= 18
convert_binary_to_sysconfcpus 'elm-make'
convert_binary_to_sysconfcpus 'elm-package'
convert_binary_to_sysconfcpus 'elm-format'
end
end

def install_elm_format
npm_install_global 'elm-format', elm_format_version

convert_binary_to_sysconfcpus 'elm-format'
end

def install_elm_test
sh.if "$(travis_vers2int $(echo `node --version` | tr -d 'v')) -lt $(travis_vers2int #{ELM_TEST_REQUIRED_NODE_VERSION})" do
sh.echo "Node.js version $(node --version) does not meet requirement for elm-test." \
" Please use Node.js #{ELM_TEST_REQUIRED_NODE_VERSION} or later.", ansi: :red
end
sh.else do
sh.if "-z \"$(command -v elm-test)\"" do
npm_install_global 'elm-test', elm_test_version

convert_binary_to_sysconfcpus 'elm-test'
end
end
end

def convert_binary_to_sysconfcpus(binary_name)
# Wrap the binary in a call to sysconfcpus -n 2
# to work around https://github.com/travis-ci/travis-ci/issues/6656
sh.mv "$(npm config get prefix)/bin/#{binary_name}", "$(npm config get prefix)/bin/#{binary_name}-old"

# Use printf instead of echo here.
# see https://github.com/rtfeldman/node-elm-compiler/pull/50
sh.cmd ('printf "#\041/bin/bash\n\necho \"Running ' + binary_name + ' with sysconfcpus -n 2\"\n\n$TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 ' + binary_name + '-old \"\$@\"" > $(npm config get prefix)/bin/' + binary_name)
sh.chmod '+x', "$(npm config get prefix)/bin/#{binary_name}"
end

def install_sysconfcpus
sh.echo 'Installing sysconfcpus', ansi: :green
sh.fold 'sysconfcpus' do
# this is a prerequisite for the convert_binary_to_sysconfcpus method
# which provides an epic build time improvement - see https://github.com/elm-lang/elm-compiler/issues/1473#issuecomment-245704142
sh.cmd 'git clone https://github.com/obmarg/libsysconfcpus.git', retry: true
sh.cd 'libsysconfcpus'
sh.cmd './configure --prefix=$TRAVIS_BUILD_DIR/sysconfcpus'
sh.cmd 'make && make install'
sh.cd '..'
end
end
end
end
end
end
44 changes: 44 additions & 0 deletions spec/build/script/elm_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
require 'spec_helper'

describe Travis::Build::Script::Elm, :sexp do
let(:data) { payload_for(:push, :elm) }
let(:script) { described_class.new(data) }
subject { script.sexp }
it { store_example }

it_behaves_like 'compiled script' do
let(:code) { ['TRAVIS_LANGUAGE=elm'] }
let(:cmds) { ['elm-test'] }
end

it_behaves_like 'a build script sexp'

it 'sets TRAVIS_ELM_VERSION' do
should include_sexp [:export, ['TRAVIS_ELM_VERSION', Travis::Build::Script::Elm::DEFAULTS[:elm]]]
end

it 'sets TRAVIS_ELM_TEST_VERSION' do
should include_sexp [:export, ['TRAVIS_ELM_TEST_VERSION', Travis::Build::Script::Elm::DEFAULTS[:elm_test]]]
end

it 'sets TRAVIS_ELM_FORMAT_VERSION' do
should include_sexp [:export, ['TRAVIS_ELM_FORMAT_VERSION', Travis::Build::Script::Elm::DEFAULTS[:elm_format]]]
end

it 'announces elm version' do
should include_sexp [:cmd, 'elm --version', echo: true]
should include_sexp [:cmd, 'elm-test --version', echo: true]
should include_sexp [:cmd, 'elm-format --help | head -n 1', echo: true]
end

describe 'script' do
it 'runs `elm-test` and `elm-format`' do
should include_sexp [:cmd, 'elm-format --validate . && elm-test', echo: true, timing: true]
end
end

describe '#cache_slug' do
subject { described_class.new(data).cache_slug }
it { is_expected.to eq("cache-#{CACHE_SLUG_EXTRAS}--node--elm-#{Travis::Build::Script::Elm::DEFAULTS[:elm]}") }
end
end

0 comments on commit 24db35b

Please sign in to comment.