vx-builder 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +15 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +29 -0
  8. data/Rakefile +40 -0
  9. data/lib/vx/builder/configuration.rb +20 -0
  10. data/lib/vx/builder/helper/config.rb +14 -0
  11. data/lib/vx/builder/helper/logger.rb +14 -0
  12. data/lib/vx/builder/helper/trace_sh_command.rb +16 -0
  13. data/lib/vx/builder/script/env.rb +21 -0
  14. data/lib/vx/builder/script/prepare.rb +59 -0
  15. data/lib/vx/builder/script/ruby.rb +59 -0
  16. data/lib/vx/builder/script/script.rb +22 -0
  17. data/lib/vx/builder/script/services.rb +25 -0
  18. data/lib/vx/builder/script/webdav_cache.rb +83 -0
  19. data/lib/vx/builder/script.rb +98 -0
  20. data/lib/vx/builder/source/constants.rb +11 -0
  21. data/lib/vx/builder/source/matrix.rb +113 -0
  22. data/lib/vx/builder/source/serializable.rb +43 -0
  23. data/lib/vx/builder/source.rb +106 -0
  24. data/lib/vx/builder/task.rb +27 -0
  25. data/lib/vx/builder/version.rb +5 -0
  26. data/lib/vx/builder.rb +38 -0
  27. data/spec/fixtures/travis.yml +5 -0
  28. data/spec/fixtures/travis_bug_1.yml +13 -0
  29. data/spec/fixtures/travis_bug_2.yml +18 -0
  30. data/spec/lib/builder/configuration_spec.rb +7 -0
  31. data/spec/lib/builder/script_spec.rb +29 -0
  32. data/spec/lib/builder/source_matrix_spec.rb +215 -0
  33. data/spec/lib/builder/source_spec.rb +183 -0
  34. data/spec/lib/builder/task_spec.rb +25 -0
  35. data/spec/lib/builder_spec.rb +17 -0
  36. data/spec/spec_helper.rb +15 -0
  37. data/spec/support/create.rb +14 -0
  38. data/spec/support/fixture.rb +7 -0
  39. data/vx-builder.gemspec +29 -0
  40. metadata +192 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4463ec3cf51845d96e765e1d95ce53f3b441dde7
4
+ data.tar.gz: 48345183e7243df3c183d729ebc353c4efa92eeb
5
+ SHA512:
6
+ metadata.gz: f0d39166126c30871d0dddb025a697b5d1f50826392d1fb898a215ca14bbcbafa1a7707622577e29b73c6474e3f7c56594b1ba23ef2c0f41f1564a8330e1c70f
7
+ data.tar.gz: 237711b5424643c4fa88a1a967727e6e3fdf3a6d4ccaa5d2d2fcdfe6e0ff052b8212477048134309cd8a50aab15f770d6c8f5a88729c015636434a78f8125cf4
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ -fd
2
+ --color
3
+ --order=rand
data/.travis.yml ADDED
@@ -0,0 +1,15 @@
1
+ rvm:
2
+ - 2.0.0
3
+
4
+ before_install:
5
+ # evrone repo
6
+ - echo 'deb http://download.opensuse.org/repositories/home:/dmexe/xUbuntu_12.04/ ./' | sudo tee /etc/apt/sources.list.d/Evrone.list
7
+ - wget -qO- http://download.opensuse.org/repositories/home:/dmexe/xUbuntu_12.04/Release.key | sudo apt-key add -
8
+ - sudo apt-get update > /dev/null
9
+ # rbenv
10
+ - sudo apt-get install rbenv -qy
11
+ - sudo apt-get install rbenv-1.9.3-p484 -qy
12
+ - sudo rbenv rehash
13
+ - sudo env RBENV_VERSION=1.9.3-p484 rbenv exec gem install bundler
14
+
15
+ script: bundle exec rake
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in vx-builder.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Dmitry Galinsky
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Vx::Builder
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'vx-builder'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install vx-builder
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler.require
4
+ require 'rspec/core/rake_task'
5
+ require "bundler/gem_tasks"
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+
9
+ desc "run spec"
10
+ task :default => [:spec]
11
+
12
+ desc "run travis build"
13
+ task :travis do
14
+ exec "bundle exec rake SPEC_OPTS='--format documentation'"
15
+ end
16
+
17
+ namespace :print do
18
+ task :script do
19
+ require 'vx/message/testing'
20
+ require File.expand_path("../spec/support/fixture", __FILE__)
21
+ require File.expand_path("../spec/support/create", __FILE__)
22
+
23
+ task = create :task
24
+ source = create :source
25
+
26
+ builder = Vx::Builder::Script.new(task, source)
27
+
28
+ puts "\n#===> BEGIN BEFORE SCRIPT"
29
+ puts builder.to_before_script
30
+ puts "#===> END BEFORE SCRIPT\n"
31
+
32
+ puts "\n#===> BEGIN SCRIPT\n"
33
+ puts builder.to_script
34
+ puts "#===> END SCRIPT\n\n"
35
+
36
+ puts "\n#===> BEGIN AFTER SCRIPT\n"
37
+ puts builder.to_after_script
38
+ puts "#===> END AFTER SCRIPT\n\n"
39
+ end
40
+ end
@@ -0,0 +1,20 @@
1
+ require 'hashr'
2
+ require 'logger'
3
+ require 'vx/common/tagged_logging'
4
+
5
+ module Vx
6
+ module Builder
7
+ class Configuration < ::Hashr
8
+
9
+ extend Hashr::EnvDefaults
10
+
11
+ self.env_namespace = 'vx'
12
+ self.raise_missing_keys = true
13
+
14
+ define logger: Common::TaggedLogging.new(Logger.new STDOUT),
15
+ webdav_cache_url: nil,
16
+ casher_ruby: "/usr/local/rbenv/versions/1.9.3-p484/bin/ruby"
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Vx
2
+ module Builder
3
+ module Helper
4
+ module Config
5
+
6
+ def config
7
+ Builder.config
8
+ end
9
+
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Vx
2
+ module Builder
3
+ module Helper
4
+ module Logger
5
+
6
+ def logger
7
+ Builder.logger
8
+ end
9
+
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ require 'shellwords'
2
+
3
+ module Vx
4
+ module Builder
5
+ module Helper
6
+
7
+ module TraceShCommand
8
+ def trace_sh_command(cmd, options = {})
9
+ trace = options[:trace] || cmd
10
+ "echo #{Shellwords.escape "$ #{trace}"}\n#{cmd}"
11
+ end
12
+ end
13
+
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,21 @@
1
+ module Vx
2
+ module Builder
3
+ class Script
4
+
5
+ Env = Struct.new(:app) do
6
+
7
+ include Helper::TraceShCommand
8
+
9
+ def call(env)
10
+ env.init << 'export LC_ALL=en_US.UTF8'
11
+ env.source.global_env.each do |e|
12
+ env.init << trace_sh_command("export #{e}")
13
+ end
14
+ env.announce << trace_sh_command("env")
15
+ app.call(env)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,59 @@
1
+ require 'vx/common'
2
+
3
+ module Vx
4
+ module Builder
5
+ class Script
6
+
7
+ Prepare = Struct.new(:app) do
8
+
9
+ include Helper::TraceShCommand
10
+ include Common::Helper::UploadShCommand
11
+
12
+ def call(env)
13
+ name = env.task.name
14
+ deploy_key = env.task.deploy_key
15
+
16
+ repo_path = "code/#{name}"
17
+ data_path = "data/#{name}"
18
+ key_file = "#{data_path}/key"
19
+ git_ssh_file = "#{data_path}/git_ssh"
20
+
21
+ sha = env.task.sha
22
+ scm = build_scm(env, sha, repo_path)
23
+ git_ssh = scm.git_ssh.class.template(deploy_key && "$(dirname $0)/key")
24
+
25
+ env.init.tap do |i|
26
+ i << "mkdir -p #{data_path}"
27
+ i << "mkdir -p #{repo_path}"
28
+
29
+ if deploy_key
30
+ i << "echo instaling keys"
31
+ i << upload_sh_command(key_file, deploy_key)
32
+ i << "chmod 0600 #{key_file}"
33
+ end
34
+
35
+ i << upload_sh_command(git_ssh_file, git_ssh)
36
+ i << "chmod 0750 #{git_ssh_file}"
37
+
38
+ i << "export GIT_SSH=$PWD/#{git_ssh_file}"
39
+ i << scm.make_fetch_command
40
+ i << "unset GIT_SSH"
41
+ end
42
+
43
+ app.call env
44
+ end
45
+
46
+ private
47
+
48
+ def build_scm(env, sha, path)
49
+ SCM::Git.new(env.task.src,
50
+ sha,
51
+ "$PWD/#{path}",
52
+ branch: env.task.branch,
53
+ pull_request_id: env.task.pull_request_id)
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,59 @@
1
+ module Vx
2
+ module Builder
3
+ class Script
4
+
5
+ Ruby = Struct.new(:app) do
6
+
7
+ include Helper::TraceShCommand
8
+
9
+ def call(env)
10
+ if rvm env
11
+ env.cache_key << "rvm-#{rvm env}"
12
+
13
+ env.before_install.tap do |i|
14
+ i << 'eval "$(rbenv init -)" || true'
15
+ i << "rbenv shell #{make_rbenv_version_command env}"
16
+ i << 'export BUNDLE_GEMFILE=${PWD}/Gemfile'
17
+ i << 'export GEM_HOME=$HOME/cached/rubygems'
18
+ end
19
+
20
+ env.announce.tap do |a|
21
+ a << trace_sh_command("ruby --version")
22
+ a << trace_sh_command("gem --version")
23
+ a << trace_sh_command("bundle --version")
24
+ end
25
+
26
+ env.install.tap do |i|
27
+ i << trace_sh_command("bundle install")
28
+ i << trace_sh_command("bundle clean --force")
29
+ end
30
+ end
31
+
32
+ app.call(env)
33
+ end
34
+
35
+ private
36
+
37
+ def rvm(env)
38
+ env.source.rvm.first
39
+ end
40
+
41
+ def make_rbenv_version_command(env)
42
+ select_rbenv_version(env)
43
+ end
44
+
45
+ def select_rbenv_version(env)
46
+ %{
47
+ $(rbenv versions |
48
+ sed -e 's/^\*/ /' |
49
+ awk '{print $1}' |
50
+ grep -v 'system' |
51
+ grep '#{rvm env}' |
52
+ tail -n1)
53
+ }.gsub(/\n/, ' ').gsub(/ +/, ' ').strip
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,22 @@
1
+ module Vx
2
+ module Builder
3
+ class Script
4
+
5
+ Script = Struct.new(:app) do
6
+
7
+ include Helper::TraceShCommand
8
+
9
+ def call(env)
10
+ env.source.before_script.each do |c|
11
+ env.before_script << trace_sh_command(c)
12
+ end
13
+ env.source.script.each do |c|
14
+ env.script << trace_sh_command(c)
15
+ end
16
+ app.call(env)
17
+ end
18
+
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,25 @@
1
+ module Vx
2
+ module Builder
3
+ class Script
4
+
5
+ Services = Struct.new(:app) do
6
+
7
+ include Helper::TraceShCommand
8
+
9
+ def call(env)
10
+ env.source.services.each do |srv|
11
+ env.init << trace_sh_command(
12
+ "sudo /usr/bin/env PATH=/sbin:/usr/sbin:$PATH service #{srv} start",
13
+ trace: "sudo service #{srv} start")
14
+ end
15
+ unless env.source.services.empty?
16
+ env.init << trace_sh_command("sleep 3")
17
+ end
18
+
19
+ app.call(env)
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,83 @@
1
+ module Vx
2
+ module Builder
3
+ class Script
4
+
5
+ WebdavCache = Struct.new(:app) do
6
+
7
+ include Helper::Config
8
+ include Helper::Logger
9
+
10
+ CASHER_URL = "https://raw.github.com/travis-ci/casher/production/bin/casher"
11
+ CASHER_BIN = "$HOME/.casher/bin/casher"
12
+
13
+ def call(env)
14
+ rs = app.call env
15
+
16
+ if config.webdav_cache_url
17
+ assign_url_to_env(env)
18
+ prepare(env)
19
+ fetch(env)
20
+ add(env)
21
+ push(env)
22
+ end
23
+
24
+ rs
25
+ end
26
+
27
+ private
28
+
29
+ def casher_cmd
30
+ "#{config.casher_ruby} #{CASHER_BIN}"
31
+ end
32
+
33
+ def assign_url_to_env(env)
34
+ urls = []
35
+ branch = env.task.branch
36
+ if branch != 'master'
37
+ urls << url_for(env, branch)
38
+ end
39
+ urls << url_for(env, 'master')
40
+
41
+ env.webdav_fetch_url = urls
42
+ env.webdav_push_url = url_for(env, branch)
43
+ env
44
+ end
45
+
46
+ def url_for(env, branch)
47
+ name = env.task.name.dup + "/" + branch
48
+
49
+ key = env.cache_key.join("-").gsub(/[^a-z0-9_\-.]/, '-')
50
+ "#{config.webdav_cache_url}/#{name}/#{key}.tgz"
51
+ end
52
+
53
+ def prepare(env)
54
+ cmd = %{
55
+ export CASHER_DIR=$HOME/.casher &&
56
+ ( mkdir -p $CASHER_DIR/bin &&
57
+ /usr/bin/curl #{CASHER_URL} -s -o #{CASHER_BIN} &&
58
+ chmod +x #{CASHER_BIN} ) ||
59
+ true
60
+ }.gsub(/\n/, ' ').gsub(/ +/, ' ')
61
+ env.init << cmd
62
+ end
63
+
64
+ def fetch(env)
65
+ urls = env.webdav_fetch_url.join(" ")
66
+ env.init << "#{casher_cmd} fetch #{urls} || true"
67
+ end
68
+
69
+ def add(env)
70
+ env.init << "#{casher_cmd} add $HOME/cached || true"
71
+ env.init << "unset CASHER_DIR"
72
+ end
73
+
74
+ def push(env)
75
+ if env.webdav_push_url
76
+ env.after_script << "#{casher_cmd} push #{env.webdav_push_url}"
77
+ end
78
+ end
79
+
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,98 @@
1
+ require 'vx/common'
2
+
3
+ module Vx
4
+ module Builder
5
+ class Script
6
+
7
+ autoload :Env, File.expand_path("../script/env", __FILE__)
8
+ autoload :Ruby, File.expand_path("../script/ruby", __FILE__)
9
+ autoload :Script, File.expand_path("../script/script", __FILE__)
10
+ autoload :Prepare, File.expand_path("../script/prepare", __FILE__)
11
+ autoload :Databases, File.expand_path("../script/databases", __FILE__)
12
+ autoload :WebdavCache, File.expand_path("../script/webdav_cache", __FILE__)
13
+ autoload :Services, File.expand_path("../script/services", __FILE__)
14
+
15
+ include Common::Helper::Middlewares
16
+
17
+ middlewares do
18
+ use Builder::Script::WebdavCache
19
+ use Builder::Script::Services
20
+ use Builder::Script::Env
21
+ use Builder::Script::Prepare
22
+ use Builder::Script::Ruby
23
+ use Builder::Script::Script
24
+ end
25
+
26
+ attr_reader :source, :task
27
+
28
+ def initialize(task, source)
29
+ @source = source
30
+ @task = task
31
+ end
32
+
33
+ def to_before_script
34
+ a = []
35
+ a << "\n# init"
36
+ a += env.init
37
+
38
+ a << "\n# before install"
39
+ a += env.before_install
40
+
41
+ a << "\n# announce"
42
+ a += env.announce
43
+
44
+ a << "\n# install"
45
+ a += env.install
46
+
47
+ a << "\n# before script"
48
+ a += env.before_script
49
+ a.join("\n")
50
+ end
51
+
52
+ def to_after_script
53
+ a = []
54
+ a << "\n# after script"
55
+ a += env.after_script
56
+ a.join("\n")
57
+ end
58
+
59
+ def to_script
60
+ a = []
61
+ a << "\n# script"
62
+ a += env.script
63
+ a.join("\n")
64
+ end
65
+
66
+ private
67
+
68
+ def env
69
+ @env ||= run_middlewares(default_env) {|_| _ }
70
+ end
71
+
72
+ def default_env
73
+ OpenStruct.new(
74
+ # initialization, repo does not exists
75
+ init: [],
76
+
77
+ # before instalation, using for system setup
78
+ before_install: [],
79
+
80
+ # instalation, using for application setup
81
+ install: [],
82
+
83
+ # announce software and services version
84
+ announce: [],
85
+
86
+ before_script: [],
87
+ script: [],
88
+ after_script: [],
89
+
90
+ source: source,
91
+ task: task,
92
+ cache_key: []
93
+ )
94
+ end
95
+
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,11 @@
1
+ module Vx
2
+ module Builder
3
+ class Source
4
+
5
+ LANGS = %w{ rvm scala java go }.freeze
6
+ KEYS = %w{ services before_script script }.freeze
7
+ AS_ARRAY = (KEYS + LANGS).freeze
8
+
9
+ end
10
+ end
11
+ end