evrone-ci-common 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +3 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +7 -0
- data/evrone-ci-common.gemspec +29 -0
- data/lib/evrone/ci/common/perform_message_wrapper.rb +50 -0
- data/lib/evrone/ci/common/shell_helper.rb +83 -0
- data/lib/evrone/ci/common/version.rb +7 -0
- data/lib/evrone/ci/common.rb +20 -0
- data/lib/evrone/ci/csm/git/git_ssh.rb +58 -0
- data/lib/evrone/ci/csm/git.rb +97 -0
- data/spec/lib/common/perform_message_wrapper_spec.rb +79 -0
- data/spec/lib/common/shell_helper_spec.rb +137 -0
- data/spec/lib/csm/git_spec.rb +100 -0
- data/spec/spec_helper.rb +11 -0
- metadata +150 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4278281c960d9b21bdd6bdb79819a48f18a9df61
|
4
|
+
data.tar.gz: dc7add247f9d9c232d4b91ee33fc3de11b431348
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e25753b2a629e1fdfa1a669fb4d046e1d040bf133e1932b5f9f0caacd01095e0ee5b3d4641151293c61d6373f98b2b1a5101cab54ae9f08b77b3022bc53036fe
|
7
|
+
data.tar.gz: 98a0937ae915d2d07ac341746d0ae3e7a98fde634fcd445456ee919d41e32c604ef1e163ffce2c45e92c82c7637a65d5569c6b2d0ee88a92721a84ae67a5287e
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
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
|
+
# Evrone::Ci::Common
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'evrone-ci-common'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install evrone-ci-common
|
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,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'evrone/ci/common/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "evrone-ci-common"
|
8
|
+
spec.version = Evrone::CI::Common::VERSION
|
9
|
+
spec.authors = ["Dmitry Galinsky"]
|
10
|
+
spec.email = ["dima.exe@gmail.com"]
|
11
|
+
spec.description = %q{ Common code for ci }
|
12
|
+
spec.summary = %q{ Common code for ci }
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'evrone-common-spawn', '0.0.3'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rspec"
|
25
|
+
spec.add_development_dependency "rr"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
|
28
|
+
spec.add_development_dependency "evrone-ci-message"
|
29
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Evrone
|
2
|
+
module CI
|
3
|
+
module Common
|
4
|
+
|
5
|
+
module PerformMessageWrapper
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send :extend, ClassMethods
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
def delegate_message_methods(msg_class, message_name)
|
14
|
+
msg_class.fields.each_pair do |_, field|
|
15
|
+
define_method field.name do
|
16
|
+
send(message_name).public_send field.name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def delivery_message_output(consumer, formatter)
|
22
|
+
|
23
|
+
define_method :output do
|
24
|
+
@output ||= ""
|
25
|
+
end
|
26
|
+
|
27
|
+
define_method :add_to_output do |data|
|
28
|
+
output << data
|
29
|
+
logger.debug data.strip if logger.level == 0
|
30
|
+
delivery_output data
|
31
|
+
end
|
32
|
+
|
33
|
+
define_method :add_command_to_output do |data|
|
34
|
+
add_to_output "$ #{data}"
|
35
|
+
add_to_output "\n"
|
36
|
+
end
|
37
|
+
|
38
|
+
define_method :delivery_output do |data|
|
39
|
+
consumer.publish send(formatter, Time.now, data).to_serialized_string
|
40
|
+
end
|
41
|
+
private :delivery_output
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'pathname'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'tempfile'
|
4
|
+
require 'shellwords'
|
5
|
+
|
6
|
+
require 'evrone/common/spawn'
|
7
|
+
|
8
|
+
module Evrone
|
9
|
+
module CI
|
10
|
+
module Common
|
11
|
+
|
12
|
+
module ShellHelper
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
include Evrone::Common::Spawn
|
17
|
+
|
18
|
+
def path(name)
|
19
|
+
Pathname.new(name)
|
20
|
+
end
|
21
|
+
|
22
|
+
def mkdir(name)
|
23
|
+
FileUtils.mkdir_p name.to_s
|
24
|
+
end
|
25
|
+
|
26
|
+
def rm(name)
|
27
|
+
FileUtils.rm_rf name.to_s
|
28
|
+
end
|
29
|
+
|
30
|
+
def recreate(name)
|
31
|
+
rm name
|
32
|
+
mkdir name
|
33
|
+
end
|
34
|
+
|
35
|
+
def write_file(name, content, perm = 0644)
|
36
|
+
File.open(name, 'w', perm) do |io|
|
37
|
+
io.write content
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def write_tmp_file(name, content, perm = 0600)
|
42
|
+
tmp = ::Tempfile.new name
|
43
|
+
tmp.write content
|
44
|
+
tmp.rewind
|
45
|
+
tmp.flush
|
46
|
+
tmp.close
|
47
|
+
FileUtils.chmod perm, tmp.path
|
48
|
+
tmp
|
49
|
+
end
|
50
|
+
|
51
|
+
def read_file(name)
|
52
|
+
if File.readable?(name)
|
53
|
+
File.read name
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def expand_path(path)
|
58
|
+
File.expand_path path.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
def bash(*args, &block)
|
62
|
+
raise ArgumentError, 'block required' unless block_given?
|
63
|
+
|
64
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
65
|
+
command = args.first
|
66
|
+
|
67
|
+
cmd = "/usr/bin/env -i HOME=${HOME} bash"
|
68
|
+
|
69
|
+
if file = options.delete(:file)
|
70
|
+
cmd << " #{file}"
|
71
|
+
else
|
72
|
+
cmd << " -c " << Shellwords.escape(command)
|
73
|
+
end
|
74
|
+
|
75
|
+
runner = options.delete(:ssh) || self
|
76
|
+
runner.send(:spawn, cmd, options, &block)
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.expand_path("../common/version", __FILE__)
|
2
|
+
|
3
|
+
module Evrone
|
4
|
+
module CI
|
5
|
+
|
6
|
+
module Common
|
7
|
+
|
8
|
+
autoload :ShellHelper, File.expand_path("../common/shell_helper", __FILE__)
|
9
|
+
autoload :PerformMessageWrapper, File.expand_path("../common/perform_message_wrapper", __FILE__)
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
module CSM
|
14
|
+
|
15
|
+
autoload :Git, File.expand_path("../csm/git", __FILE__)
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Evrone
|
2
|
+
module CI
|
3
|
+
module CSM
|
4
|
+
|
5
|
+
class Git
|
6
|
+
|
7
|
+
class GitSSH
|
8
|
+
|
9
|
+
include Common::ShellHelper
|
10
|
+
|
11
|
+
attr_reader :deploy_key
|
12
|
+
|
13
|
+
def initialize(deploy_key)
|
14
|
+
@deploy_key = deploy_key
|
15
|
+
end
|
16
|
+
|
17
|
+
def open
|
18
|
+
begin
|
19
|
+
yield create
|
20
|
+
ensure
|
21
|
+
destroy
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def create
|
26
|
+
key_location
|
27
|
+
location
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
key_location.unlink if key_location
|
32
|
+
location.unlink
|
33
|
+
@location = nil
|
34
|
+
@key_location = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def location
|
38
|
+
@location ||= write_tmp_file 'git', template, 0700
|
39
|
+
end
|
40
|
+
|
41
|
+
def key_location
|
42
|
+
if deploy_key
|
43
|
+
@key_location ||= write_tmp_file 'key', deploy_key, 0600
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def template
|
48
|
+
key = key_location ? "-i #{key_location.path}" : ""
|
49
|
+
out = ['#!/bin/sh']
|
50
|
+
out << "exec /usr/bin/ssh -A -o StrictHostKeyChecking=no #{key} $@"
|
51
|
+
out.join "\n"
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require File.expand_path("../git/git_ssh", __FILE__)
|
3
|
+
|
4
|
+
module Evrone
|
5
|
+
module CI
|
6
|
+
module CSM
|
7
|
+
|
8
|
+
class Git
|
9
|
+
|
10
|
+
include Common::ShellHelper
|
11
|
+
|
12
|
+
COMMIT_RE = /^(.*) -:- (.*) \((.*)\) -:- (.*)$/
|
13
|
+
|
14
|
+
attr_reader :src, :sha, :path, :logger, :git_ssh
|
15
|
+
|
16
|
+
def initialize(src, sha, path, options = {}, &block)
|
17
|
+
@src = src
|
18
|
+
@sha = sha
|
19
|
+
@path = path
|
20
|
+
@git_ssh = GitSSH.new options[:deploy_key]
|
21
|
+
@logger = block
|
22
|
+
end
|
23
|
+
|
24
|
+
def fetch
|
25
|
+
code = git_ssh.open do
|
26
|
+
repo_exist? ? update : clone
|
27
|
+
end
|
28
|
+
code = checkout if code == 0
|
29
|
+
code
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.make_export_command(from, to)
|
33
|
+
%{ (cd '#{from}' && git checkout-index -a -f --prefix='#{to}/') }.strip
|
34
|
+
end
|
35
|
+
|
36
|
+
def commit_info
|
37
|
+
rs = {}
|
38
|
+
if str = commit_info_string
|
39
|
+
if m = str.match(COMMIT_RE)
|
40
|
+
rs.merge!(
|
41
|
+
sha: m[1],
|
42
|
+
author: m[2],
|
43
|
+
email: m[3],
|
44
|
+
message: m[4]
|
45
|
+
)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
OpenStruct.new rs
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def commit_info_string
|
54
|
+
output = ""
|
55
|
+
code = spawn commit_info_cmd, chdir: path do |io|
|
56
|
+
output << io
|
57
|
+
end
|
58
|
+
if code == 0
|
59
|
+
output.strip
|
60
|
+
else
|
61
|
+
nil
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def commit_info_cmd
|
66
|
+
%{git log -1 --pretty=format:'%H -:- %cn (%ce) -:- %s'}
|
67
|
+
end
|
68
|
+
|
69
|
+
def repo_exist?
|
70
|
+
File.directory?(path.to_s + "/.git")
|
71
|
+
end
|
72
|
+
|
73
|
+
def update
|
74
|
+
run_git 'git fetch origin', chdir: path
|
75
|
+
end
|
76
|
+
|
77
|
+
def clone
|
78
|
+
run_git "git clone -q '#{src}' '#{path}'"
|
79
|
+
end
|
80
|
+
|
81
|
+
def checkout
|
82
|
+
run_git "git checkout -qf #{sha}", chdir: path
|
83
|
+
end
|
84
|
+
|
85
|
+
def run_git(cmd, options = {})
|
86
|
+
env = {
|
87
|
+
'GIT_SSH' => git_ssh.location.path
|
88
|
+
}
|
89
|
+
logger.call "$ #{cmd}\n"
|
90
|
+
spawn(env, cmd, options, &logger)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'logger'
|
3
|
+
require 'evrone/ci/message/testing'
|
4
|
+
|
5
|
+
class PerformMessageWrapperConsumer
|
6
|
+
def self.publish(*args)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
PerformMessageWrapperTest = Struct.new(:message) do
|
11
|
+
|
12
|
+
include Evrone::CI::Common::PerformMessageWrapper
|
13
|
+
|
14
|
+
delegate_message_methods Evrone::CI::Message::PerformBuild, :message
|
15
|
+
delivery_message_output PerformMessageWrapperConsumer, :make_log_message
|
16
|
+
|
17
|
+
def make_log_message(tm, data)
|
18
|
+
Evrone::CI::Message::BuildLog.new build_id: id, tm: tm.to_i, tm_usec: tm.usec, log: data
|
19
|
+
end
|
20
|
+
|
21
|
+
def logger
|
22
|
+
@logger ||= Logger.new(STDOUT).tap{|l| l.level = 0 }
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
describe Evrone::CI::Common::PerformMessageWrapper do
|
28
|
+
let(:consumer) { PerformMessageWrapperConsumer }
|
29
|
+
let(:klass) { PerformMessageWrapperTest }
|
30
|
+
let(:message) { Evrone::CI::Message::PerformBuild.test_message }
|
31
|
+
let(:object) { klass.new message }
|
32
|
+
|
33
|
+
subject { object }
|
34
|
+
|
35
|
+
it { should be }
|
36
|
+
|
37
|
+
its(:output) { should eq '' }
|
38
|
+
its(:id) { should eq message.id }
|
39
|
+
its(:name) { should eq message.name }
|
40
|
+
its(:src) { should eq message.src }
|
41
|
+
its(:sha) { should eq message.sha }
|
42
|
+
its(:deploy_key) { should eq message.deploy_key }
|
43
|
+
|
44
|
+
context "add_to_output" do
|
45
|
+
|
46
|
+
subject { object.add_to_output "line" }
|
47
|
+
|
48
|
+
before do
|
49
|
+
mock(consumer).publish(anything) { true }
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should delivery message" do
|
53
|
+
expect(subject).to be
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should add message to output" do
|
57
|
+
subject
|
58
|
+
expect(object.output).to eq 'line'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "add_command_to_output" do
|
63
|
+
|
64
|
+
subject { object.add_command_to_output "line" }
|
65
|
+
|
66
|
+
before do
|
67
|
+
mock(consumer).publish(anything).twice { true }
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should delivery formatted message" do
|
71
|
+
expect(subject).to be
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should add formatted message to output" do
|
75
|
+
subject
|
76
|
+
expect(object.output).to eq "$ line\n"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Evrone::CI::Common::ShellHelper do
|
4
|
+
|
5
|
+
let(:klass) { Class.new.tap{|i| i.send :include, described_class } }
|
6
|
+
let(:object) { klass.new }
|
7
|
+
|
8
|
+
subject { object }
|
9
|
+
|
10
|
+
context "path" do
|
11
|
+
it "should create Pathname" do
|
12
|
+
expect_method(:path, '/tmp').to eq Pathname.new('/tmp')
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "mkdir" do
|
17
|
+
|
18
|
+
after { FileUtils.rm_rf '/tmp/.a/' }
|
19
|
+
|
20
|
+
it "should create directories" do
|
21
|
+
expect_method(:mkdir, '/tmp/.a/b/c')
|
22
|
+
expect(File.directory? '/tmp/.a/b/c')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "rm" do
|
27
|
+
before { FileUtils.mkdir_p '/tmp/.a/b/c' }
|
28
|
+
after { FileUtils.rm_rf '/tmp/.a' }
|
29
|
+
|
30
|
+
it "should force remove" do
|
31
|
+
expect_method :rm, '/tmp/.a'
|
32
|
+
expect(File.exists? '/tmp/.a').to be_false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "recreate" do
|
37
|
+
before { FileUtils.mkdir_p '/tmp/.a/b/c' }
|
38
|
+
after { FileUtils.rm_rf '/tmp/.a' }
|
39
|
+
|
40
|
+
it "should remove and create directory" do
|
41
|
+
expect_method :recreate, '/tmp/.a/b'
|
42
|
+
expect(File.exists? '/tmp/.a/b/c').to be_false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "write_file" do
|
47
|
+
let(:fname) { '/tmp/.a' }
|
48
|
+
after { FileUtils.rm_f fname }
|
49
|
+
|
50
|
+
it "should write content to file" do
|
51
|
+
expect_method :write_file, fname, 'content', 0611
|
52
|
+
expect(File.readable? fname).to be_true
|
53
|
+
expect(File.read fname).to eq 'content'
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "write_tmp_file" do
|
58
|
+
let(:tmp_file) { object.send :write_tmp_file, 'fname', 'content', 0611 }
|
59
|
+
|
60
|
+
after { FileUtils.rm_f tmp_file.path }
|
61
|
+
|
62
|
+
it "should create tmp file and write content" do
|
63
|
+
expect(tmp_file).to be
|
64
|
+
expect(File.readable? tmp_file.path).to be_true
|
65
|
+
expect(File.read tmp_file.path).to eq 'content'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context "read_file" do
|
70
|
+
let(:fname) { '/tmp/.a' }
|
71
|
+
before do
|
72
|
+
File.open fname, 'w' do |io|
|
73
|
+
io << "content"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
after { FileUtils.rm_f fname }
|
77
|
+
|
78
|
+
it "should read file" do
|
79
|
+
expect_method(:read_file, fname).to eq 'content'
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when file does not exists" do
|
83
|
+
it "should return nil" do
|
84
|
+
expect_method(:read_file, 'not_exists').to be_nil
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
context "bash" do
|
90
|
+
let(:output) { '' }
|
91
|
+
|
92
|
+
context "when command is string" do
|
93
|
+
it "should spawn bash command and return exit code" do
|
94
|
+
expect_method(:bash, "echo $HOME", &method(:add_to_output)).to eq 0
|
95
|
+
expect(output).to eq ENV['HOME'] + "\n"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when command is a file" do
|
100
|
+
let(:fname) { '/tmp/.a' }
|
101
|
+
|
102
|
+
before do
|
103
|
+
File.open fname, 'w' do |io|
|
104
|
+
io << "echo $HOME"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
after { FileUtils.rm_f fname }
|
109
|
+
|
110
|
+
it "should spawn bash, execute file and return exit code" do
|
111
|
+
expect_method(:bash, file: fname, &method(:add_to_output)).to eq 0
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when :ssh options passed" do
|
116
|
+
let(:ssh) { 'ssh' }
|
117
|
+
|
118
|
+
before do
|
119
|
+
mock(ssh).spawn("/usr/bin/env -i HOME=${HOME} bash -c command", {}) { 0 }
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should execute command thougth :ssh" do
|
123
|
+
expect_method(:bash, 'command', ssh: ssh, &method(:add_to_output)).to eq 0
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
def add_to_output(out)
|
129
|
+
output << out
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def expect_method(name, *args, &block)
|
134
|
+
expect(object.send(name, *args, &block))
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'evrone/ci/message/testing'
|
3
|
+
|
4
|
+
describe Evrone::CI::CSM::Git do
|
5
|
+
let(:path) { '/tmp/.test/repo' }
|
6
|
+
let(:message) { Evrone::CI::Message::PerformBuild.test_message }
|
7
|
+
let(:src) { message.src }
|
8
|
+
let(:sha) { message.sha }
|
9
|
+
let(:deploy_key) { message.deploy_key }
|
10
|
+
let(:output) { "" }
|
11
|
+
let(:git) {
|
12
|
+
described_class.new src, sha, path, deploy_key: deploy_key, &method(:add_to_output)
|
13
|
+
}
|
14
|
+
|
15
|
+
subject { git }
|
16
|
+
|
17
|
+
before { FileUtils.rm_rf path }
|
18
|
+
after { FileUtils.rm_rf path }
|
19
|
+
|
20
|
+
context "just created" do
|
21
|
+
its(:src) { should eq src }
|
22
|
+
its(:sha) { should eq sha }
|
23
|
+
its(:path) { should eq path }
|
24
|
+
its("git_ssh.deploy_key") { should eq deploy_key }
|
25
|
+
end
|
26
|
+
|
27
|
+
context "fetch" do
|
28
|
+
subject { git.fetch }
|
29
|
+
|
30
|
+
it { should eq 0 }
|
31
|
+
|
32
|
+
it "should create nessesary deirectories and checkout sha" do
|
33
|
+
subject
|
34
|
+
expect(File.directory? path).to be
|
35
|
+
expect(File.directory? "#{path}/.git").to be
|
36
|
+
Dir.chdir path do
|
37
|
+
expect((`git rev-parse HEAD`).strip).to eq sha
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should capture output" do
|
42
|
+
subject
|
43
|
+
expect(output).to eq "$ git clone -q '#{src}' '#{path}'\n$ git checkout -qf #{sha}\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
context "twice" do
|
47
|
+
before { git.fetch }
|
48
|
+
it { should eq 0 }
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with error" do
|
52
|
+
let(:src) { "/not-exists-repo.git" }
|
53
|
+
|
54
|
+
it "should return 128 exitstatus and add error to output" do
|
55
|
+
expect(subject).to eq 128
|
56
|
+
expect(output).to match('does not exist')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context ".make_export_command" do
|
62
|
+
let(:from) { path }
|
63
|
+
let(:to) { '/tmp/.test/export' }
|
64
|
+
let(:expected) { "(cd '#{from}' && git checkout-index -a -f --prefix='#{to}/')" }
|
65
|
+
subject { described_class.make_export_command from, to}
|
66
|
+
it { should eq expected }
|
67
|
+
|
68
|
+
context "run" do
|
69
|
+
before do
|
70
|
+
git.fetch
|
71
|
+
system subject
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be success" do
|
75
|
+
expect($?.to_i).to eq 0
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should export repo" do
|
79
|
+
expect(File.readable? "#{to}/Gemfile").to be_true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "commit_info" do
|
85
|
+
subject { git.commit_info }
|
86
|
+
before { git.fetch }
|
87
|
+
|
88
|
+
it "should be" do
|
89
|
+
expect(subject.sha).to eq 'b665f90239563c030f1b280a434b3d84daeda1bd'
|
90
|
+
expect(subject.author).to eq "Dmitry Galinsky"
|
91
|
+
expect(subject.email).to eq 'dima.exe@gmail.com'
|
92
|
+
expect(subject.message).to eq 'first release'
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def add_to_output(out)
|
97
|
+
puts "==> #{out}"
|
98
|
+
output << out
|
99
|
+
end
|
100
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.expand_path '../../lib/evrone/ci/common', __FILE__
|
2
|
+
|
3
|
+
Bundler.require(:test)
|
4
|
+
|
5
|
+
require 'rspec/autorun'
|
6
|
+
|
7
|
+
Dir[File.expand_path("../..", __FILE__) + "/spec/support/**/*.rb"].each {|f| require f}
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.mock_with :rr
|
11
|
+
end
|
metadata
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: evrone-ci-common
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dmitry Galinsky
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-24 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: evrone-common-spawn
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.3
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.3
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rr
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: evrone-ci-message
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: ' Common code for ci '
|
98
|
+
email:
|
99
|
+
- dima.exe@gmail.com
|
100
|
+
executables: []
|
101
|
+
extensions: []
|
102
|
+
extra_rdoc_files: []
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- .rspec
|
106
|
+
- .travis.yml
|
107
|
+
- Gemfile
|
108
|
+
- LICENSE.txt
|
109
|
+
- README.md
|
110
|
+
- Rakefile
|
111
|
+
- evrone-ci-common.gemspec
|
112
|
+
- lib/evrone/ci/common.rb
|
113
|
+
- lib/evrone/ci/common/perform_message_wrapper.rb
|
114
|
+
- lib/evrone/ci/common/shell_helper.rb
|
115
|
+
- lib/evrone/ci/common/version.rb
|
116
|
+
- lib/evrone/ci/csm/git.rb
|
117
|
+
- lib/evrone/ci/csm/git/git_ssh.rb
|
118
|
+
- spec/lib/common/perform_message_wrapper_spec.rb
|
119
|
+
- spec/lib/common/shell_helper_spec.rb
|
120
|
+
- spec/lib/csm/git_spec.rb
|
121
|
+
- spec/spec_helper.rb
|
122
|
+
homepage: ''
|
123
|
+
licenses:
|
124
|
+
- MIT
|
125
|
+
metadata: {}
|
126
|
+
post_install_message:
|
127
|
+
rdoc_options: []
|
128
|
+
require_paths:
|
129
|
+
- lib
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - '>='
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
requirements: []
|
141
|
+
rubyforge_project:
|
142
|
+
rubygems_version: 2.0.2
|
143
|
+
signing_key:
|
144
|
+
specification_version: 4
|
145
|
+
summary: Common code for ci
|
146
|
+
test_files:
|
147
|
+
- spec/lib/common/perform_message_wrapper_spec.rb
|
148
|
+
- spec/lib/common/shell_helper_spec.rb
|
149
|
+
- spec/lib/csm/git_spec.rb
|
150
|
+
- spec/spec_helper.rb
|