perkins 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.env.example +4 -0
- data/.gitignore +19 -0
- data/.pryrc +3 -0
- data/.rspec +2 -0
- data/Gemfile +18 -0
- data/LICENSE.txt +22 -0
- data/README.md +71 -0
- data/Rakefile +28 -0
- data/TODO.md +4 -0
- data/bin/perkins +6 -0
- data/db/migrate/20150130143030_create_repo.rb +18 -0
- data/db/migrate/20150130143050_create_builds.rb +20 -0
- data/db/schema.rb +38 -0
- data/examples/config.rb +12 -0
- data/examples/database.yml +17 -0
- data/examples/mongo.yml +13 -0
- data/lib/core_ext/hash/compact.rb +8 -0
- data/lib/core_ext/hash/deep_merge.rb +15 -0
- data/lib/core_ext/hash/deep_symbolize_keys.rb +20 -0
- data/lib/core_ext/object/false.rb +5 -0
- data/lib/core_ext/string/indent.rb +5 -0
- data/lib/core_ext/string/unindent.rb +5 -0
- data/lib/perkins/.DS_Store +0 -0
- data/lib/perkins/application.rb +40 -0
- data/lib/perkins/assets/images/github.svg +4 -0
- data/lib/perkins/assets/images/spinner.svg +23 -0
- data/lib/perkins/assets/javascripts/app.js +9 -0
- data/lib/perkins/assets/javascripts/log_view.js.coffee +95 -0
- data/lib/perkins/assets/javascripts/perkings.js.coffee +40 -0
- data/lib/perkins/assets/javascripts/vendor/ansiparse.js +187 -0
- data/lib/perkins/assets/javascripts/vendor/jquery.timeago.js +189 -0
- data/lib/perkins/assets/javascripts/vendor/log.js +2 -0
- data/lib/perkins/assets/javascripts/vendor/minispade.js +55 -0
- data/lib/perkins/assets/stylesheets/app.css +2 -0
- data/lib/perkins/assets/stylesheets/log.css.scss +115 -0
- data/lib/perkins/assets/stylesheets/styles.css.scss +199 -0
- data/lib/perkins/auth/github.rb +181 -0
- data/lib/perkins/build/data/env.rb +84 -0
- data/lib/perkins/build/data/var.rb +60 -0
- data/lib/perkins/build/data.rb +167 -0
- data/lib/perkins/build/script/bundler.rb +76 -0
- data/lib/perkins/build/script/go.rb +100 -0
- data/lib/perkins/build/script/helpers.rb +39 -0
- data/lib/perkins/build/script/jdk.rb +43 -0
- data/lib/perkins/build/script/ruby.rb +31 -0
- data/lib/perkins/build/script/rvm.rb +73 -0
- data/lib/perkins/build/script/stages.rb +28 -0
- data/lib/perkins/build/script/templates/footer.sh +3 -0
- data/lib/perkins/build/script/templates/header.sh +201 -0
- data/lib/perkins/build/script/templates/xcode.sh +21 -0
- data/lib/perkins/build/script.rb +167 -0
- data/lib/perkins/build/shell/dsl.rb +104 -0
- data/lib/perkins/build/shell/node.rb +121 -0
- data/lib/perkins/build/shell.rb +16 -0
- data/lib/perkins/build.rb +27 -0
- data/lib/perkins/build_report.rb +11 -0
- data/lib/perkins/cli.rb +42 -0
- data/lib/perkins/commit.rb +30 -0
- data/lib/perkins/dsl/app_proxy.rb +23 -0
- data/lib/perkins/dsl.rb +12 -0
- data/lib/perkins/listener.rb +38 -0
- data/lib/perkins/logger.rb +12 -0
- data/lib/perkins/notifier.rb +5 -0
- data/lib/perkins/repo.rb +145 -0
- data/lib/perkins/runner.rb +124 -0
- data/lib/perkins/server.rb +314 -0
- data/lib/perkins/thor_utils.rb +79 -0
- data/lib/perkins/version.rb +3 -0
- data/lib/perkins/views/401.haml +1 -0
- data/lib/perkins/views/builds.haml +46 -0
- data/lib/perkins/views/index.haml +6 -0
- data/lib/perkins/views/layout.haml +53 -0
- data/lib/perkins/views/menu.haml +18 -0
- data/lib/perkins/views/orgs.haml +101 -0
- data/lib/perkins/views/profile.haml +31 -0
- data/lib/perkins/views/readme.md +20 -0
- data/lib/perkins/views/repos/config.haml +72 -0
- data/lib/perkins/views/repos/github.haml +76 -0
- data/lib/perkins/views/repos/menu.haml +17 -0
- data/lib/perkins/views/repos/repo.haml +64 -0
- data/lib/perkins/views/repos/spinner.haml +3 -0
- data/lib/perkins/webhooks/github.rb +12 -0
- data/lib/perkins/worker.rb +33 -0
- data/lib/perkins.rb +36 -0
- data/perkins.gemspec +52 -0
- data/spec/fixtures/.travis.yml +8 -0
- data/spec/fixtures/config.yml +6 -0
- data/spec/lib/build/build_spec.rb +58 -0
- data/spec/lib/commit_spec.rb +6 -0
- data/spec/lib/dsl_spec.rb +17 -0
- data/spec/lib/listener_spec.rb +30 -0
- data/spec/lib/repo_spec.rb +110 -0
- data/spec/lib/runner_spec.rb +76 -0
- data/spec/lib/server_spec.rb +108 -0
- data/spec/spec_helper.rb +67 -0
- data/spec/support/auth.rb +30 -0
- data/spec/support/github_api.rb +177 -0
- metadata +503 -0
@@ -0,0 +1,167 @@
|
|
1
|
+
require 'core_ext/hash/deep_merge'
|
2
|
+
require 'core_ext/hash/deep_symbolize_keys'
|
3
|
+
require 'core_ext/object/false'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module Perkins
|
7
|
+
module Build
|
8
|
+
class Script
|
9
|
+
autoload :Helpers, 'perkins/build/script/helpers'
|
10
|
+
|
11
|
+
#autoload :Stages, 'perkins/build/script/stages'
|
12
|
+
#autoload :Ruby, 'perkins/build/script/ruby'
|
13
|
+
#autoload :Go, 'perkins/build/script/go'
|
14
|
+
|
15
|
+
#autoload :Addons, 'perkins/build/script/addons'
|
16
|
+
#autoload :Android, 'perkins/build/script/android'
|
17
|
+
autoload :Bundler, 'perkins/build/script/bundler'
|
18
|
+
#autoload :C, 'perkins/build/script/c'
|
19
|
+
#autoload :Cpp, 'perkins/build/script/cpp'
|
20
|
+
#autoload :Clojure, 'perkins/build/script/clojure'
|
21
|
+
#autoload :DirectoryCache, 'perkins/build/script/directory_cache'
|
22
|
+
#autoload :Erlang, 'perkins/build/script/erlang'
|
23
|
+
#autoload :Git, 'perkins/build/script/git'
|
24
|
+
autoload :Go, 'perkins/build/script/go'
|
25
|
+
#autoload :Groovy, 'perkins/build/script/groovy'
|
26
|
+
#autoload :Generic, 'perkins/build/script/generic'
|
27
|
+
#autoload :Haskell, 'perkins/build/script/haskell'
|
28
|
+
autoload :Helpers, 'perkins/build/script/helpers'
|
29
|
+
autoload :Jdk, 'perkins/build/script/jdk'
|
30
|
+
#autoload :Jvm, 'perkins/build/script/jvm'
|
31
|
+
#autoload :NodeJs, 'perkins/build/script/node_js'
|
32
|
+
#autoload :ObjectiveC, 'perkins/build/script/objective_c'
|
33
|
+
#autoload :Perl, 'perkins/build/script/perl'
|
34
|
+
#autoload :Php, 'perkins/build/script/php'
|
35
|
+
#autoload :PureJava, 'perkins/build/script/pure_java'
|
36
|
+
#autoload :Python, 'perkins/build/script/python'
|
37
|
+
autoload :Ruby, 'perkins/build/script/ruby'
|
38
|
+
#autoload :Rust, 'perkins/build/script/rust'
|
39
|
+
autoload :RVM, 'perkins/build/script/rvm'
|
40
|
+
#autoload :Scala, 'perkins/build/script/scala'
|
41
|
+
autoload :Services, 'perkins/build/script/services'
|
42
|
+
autoload :Stages, 'perkins/build/script/stages'
|
43
|
+
|
44
|
+
TEMPLATES_PATH = File.expand_path('../script/templates', __FILE__)
|
45
|
+
|
46
|
+
STAGES = {
|
47
|
+
builtin: [:configure, :checkout, :pre_setup, :export, :setup, :announce],
|
48
|
+
custom: [:before_install, :install, :before_script, :script, :after_result, :after_script]
|
49
|
+
}
|
50
|
+
|
51
|
+
attr_reader :stack, :repo, :config
|
52
|
+
attr_reader :data, :options
|
53
|
+
|
54
|
+
class << self
|
55
|
+
def defaults
|
56
|
+
self::DEFAULTS
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
include Helpers, Stages
|
62
|
+
|
63
|
+
def initialize(data, repo)
|
64
|
+
@config = data #used in runner
|
65
|
+
@repo = repo
|
66
|
+
#@stack = []
|
67
|
+
@data = Data.new({ config: self.class.defaults }.deep_merge(data.deep_symbolize_keys))
|
68
|
+
@options = options
|
69
|
+
@stack = [Shell::Script.new(echo: true, timing: true)]
|
70
|
+
end
|
71
|
+
|
72
|
+
#run stages
|
73
|
+
def compile
|
74
|
+
#run_stages if check_config
|
75
|
+
#@stack.compact.join(" && ")
|
76
|
+
raw template 'header.sh'
|
77
|
+
run_stages.compact if check_config
|
78
|
+
raw template 'footer.sh'
|
79
|
+
sh.to_s
|
80
|
+
end
|
81
|
+
|
82
|
+
private
|
83
|
+
|
84
|
+
def check_config
|
85
|
+
case data.config.present? #[:".result"]
|
86
|
+
when 'not_found'
|
87
|
+
echo 'Could not find .travis.yml, using standard configuration.', ansi: :red
|
88
|
+
true
|
89
|
+
when 'server_error'
|
90
|
+
echo 'Could not fetch .travis.yml from GitHub.', ansi: :red
|
91
|
+
raw 'travis_terminate 2'
|
92
|
+
false
|
93
|
+
else
|
94
|
+
true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def config
|
99
|
+
data.config
|
100
|
+
end
|
101
|
+
|
102
|
+
def export
|
103
|
+
=begin
|
104
|
+
set 'TRAVIS', 'true', echo: false
|
105
|
+
set 'CI', 'true', echo: false
|
106
|
+
set 'CONTINUOUS_INTEGRATION', 'true', echo: false
|
107
|
+
set 'HAS_JOSH_K_SEAL_OF_APPROVAL', 'true', echo: false
|
108
|
+
|
109
|
+
newline if data.env_vars_groups.any?(&:announce?)
|
110
|
+
|
111
|
+
data.env_vars_groups.each do |group|
|
112
|
+
echo "Setting environment variables from #{group.source}", ansi: :yellow if group.announce?
|
113
|
+
group.vars.each { |var| set var.key, var.value, echo: var.to_s }
|
114
|
+
end
|
115
|
+
|
116
|
+
newline if data.env_vars_groups.any?(&:announce?)
|
117
|
+
=end
|
118
|
+
end
|
119
|
+
|
120
|
+
def finish
|
121
|
+
puts "finish"
|
122
|
+
#"push_directory_cache"
|
123
|
+
end
|
124
|
+
|
125
|
+
def pre_setup
|
126
|
+
puts "pre setup"
|
127
|
+
#start_services
|
128
|
+
#setup_apt_cache if data.cache? :apt
|
129
|
+
#fix_ps4
|
130
|
+
#run_addons(:after_pre_setup)
|
131
|
+
end
|
132
|
+
|
133
|
+
def setup
|
134
|
+
puts "setup"
|
135
|
+
#setup_directory_cache
|
136
|
+
end
|
137
|
+
|
138
|
+
def announce
|
139
|
+
# overwrite
|
140
|
+
end
|
141
|
+
|
142
|
+
def configure
|
143
|
+
#fix_resolv_conf
|
144
|
+
#fix_etc_hosts
|
145
|
+
end
|
146
|
+
|
147
|
+
#instance git repo
|
148
|
+
def checkout
|
149
|
+
@repo.load_git
|
150
|
+
nil
|
151
|
+
end
|
152
|
+
|
153
|
+
STAGES[:custom].each do |meth|
|
154
|
+
define_method(meth) do
|
155
|
+
puts "performing default #{meth}"
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def template(filename)
|
160
|
+
@working_dir = @repo.working_dir + @repo.name
|
161
|
+
ERB.new(File.read(File.expand_path(filename, TEMPLATES_PATH))).result(binding)
|
162
|
+
end
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Perkins
|
2
|
+
module Build
|
3
|
+
module Shell
|
4
|
+
module Dsl
|
5
|
+
def script(*args, &block)
|
6
|
+
nodes << Script.new(*merge_options(args), &block)
|
7
|
+
nodes.last
|
8
|
+
end
|
9
|
+
|
10
|
+
def cmd(code, *args)
|
11
|
+
options = args.last.is_a?(Hash) ? args.last : {}
|
12
|
+
node = Cmd.new(code, *merge_options(args))
|
13
|
+
options[:fold] ? fold(options[:fold]) { raw(node) } : raw(node)
|
14
|
+
end
|
15
|
+
|
16
|
+
def raw(code, *args)
|
17
|
+
args = merge_options(args)
|
18
|
+
pos = args.last.delete(:pos) || -1
|
19
|
+
node = code.is_a?(Node) ? code : Node.new(code, *args)
|
20
|
+
nodes.insert(pos, node)
|
21
|
+
end
|
22
|
+
|
23
|
+
def export(name, value, options = {})
|
24
|
+
cmd "export #{name}=#{value}", { assert: false, timing: false }.merge(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
def set(name, value, options = {})
|
28
|
+
cmd "export #{name}=#{value}", { assert: false, timing: false }.merge(options)
|
29
|
+
end
|
30
|
+
#alias set export
|
31
|
+
|
32
|
+
def echo(string, options = {})
|
33
|
+
string = ansi(string, options) if options[:ansi]
|
34
|
+
cmd "echo -e #{escape(string)}", { assert: false, echo: false, timing: false }.merge(options)
|
35
|
+
end
|
36
|
+
|
37
|
+
def newline
|
38
|
+
raw 'echo'
|
39
|
+
end
|
40
|
+
|
41
|
+
def cd(path)
|
42
|
+
cmd "cd #{path}", echo: true, timing: false
|
43
|
+
end
|
44
|
+
|
45
|
+
def file(path, content)
|
46
|
+
raw "echo #{escape(content)} > #{path}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def if(*args, &block)
|
50
|
+
args = merge_options(args)
|
51
|
+
els_ = args.last.delete(:else)
|
52
|
+
nodes << If.new(*args, &block)
|
53
|
+
self.else(els_, args.last) if els_
|
54
|
+
nodes.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def elif(*args, &block)
|
58
|
+
raise InvalidParent.new(Elif, If, nodes.last.class) unless nodes.last.is_a?(If)
|
59
|
+
args = merge_options(args)
|
60
|
+
els_ = args.last.delete(:else)
|
61
|
+
nodes.last.raw Elif.new(*args, &block)
|
62
|
+
self.else(els_, args.last) if els_
|
63
|
+
nodes.last
|
64
|
+
end
|
65
|
+
|
66
|
+
def else(*args, &block)
|
67
|
+
raise InvalidParent.new(Else, If, nodes.last.class) unless nodes.last.is_a?(If)
|
68
|
+
nodes.last.raw Else.new(*merge_options(args), &block)
|
69
|
+
nodes.last
|
70
|
+
end
|
71
|
+
|
72
|
+
def fold(name, &block)
|
73
|
+
raw "travis_fold start #{name}"
|
74
|
+
result = yield(self)
|
75
|
+
raw "travis_fold end #{name}"
|
76
|
+
result
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def merge_options(args, options = {})
|
82
|
+
options = (args.last.is_a?(Hash) ? args.pop : {}).merge(options)
|
83
|
+
args << self.options.merge(options)
|
84
|
+
end
|
85
|
+
|
86
|
+
ANSI = {
|
87
|
+
green: '\033[32;1m',
|
88
|
+
red: '\033[31;1m',
|
89
|
+
yellow: '\033[33;1m',
|
90
|
+
reset: '\033[0m'
|
91
|
+
}
|
92
|
+
|
93
|
+
def ansi(string, options)
|
94
|
+
keys = Array(options[:ansi])
|
95
|
+
prefix = keys.map { |key| ANSI[key] }
|
96
|
+
lines = string.split("\n").map do |line|
|
97
|
+
line.strip.empty? ? line : [prefix, line, ANSI[:reset]].flatten.join
|
98
|
+
end
|
99
|
+
lines.join("\n")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'core_ext/string/indent'
|
3
|
+
|
4
|
+
module Perkins
|
5
|
+
module Build
|
6
|
+
module Shell
|
7
|
+
class Node
|
8
|
+
attr_reader :code, :options, :level
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
@options = args.last.is_a?(Hash) ? args.pop : {}
|
12
|
+
@level = options.delete(:level) || 0
|
13
|
+
@code = args.first
|
14
|
+
yield(self) if block_given?
|
15
|
+
end
|
16
|
+
|
17
|
+
def name
|
18
|
+
self.class.name.split('::').last.downcase
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_s
|
22
|
+
code ? code.indent(level) : code
|
23
|
+
end
|
24
|
+
|
25
|
+
def escape(code)
|
26
|
+
Shellwords.escape(code)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Cmd < Node
|
31
|
+
def code
|
32
|
+
if opts.any?
|
33
|
+
['travis_cmd', escape(super), *opts].join(' ')
|
34
|
+
else
|
35
|
+
super
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def opts
|
40
|
+
opts ||= []
|
41
|
+
opts << '--assert' if options[:assert]
|
42
|
+
opts << '--echo' if options[:echo]
|
43
|
+
opts << '--retry' if options[:retry]
|
44
|
+
opts << '--timing' if options[:timing]
|
45
|
+
opts << "--display #{escape(options[:echo])}" if options[:echo].is_a?(String)
|
46
|
+
opts
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class Group < Node
|
51
|
+
include Dsl
|
52
|
+
|
53
|
+
attr_reader :nodes
|
54
|
+
|
55
|
+
def initialize(*args, &block)
|
56
|
+
@options = args.last.is_a?(Hash) ? args.pop : {}
|
57
|
+
@level = options.delete(:level) || 0
|
58
|
+
@nodes = []
|
59
|
+
args.map { |node| cmd(node, options) }
|
60
|
+
yield(self) if block_given?
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_s
|
64
|
+
nodes.map(&:to_s).join("\n").indent(level)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class Script < Group
|
69
|
+
def to_s
|
70
|
+
super + "\n"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
class Block < Group
|
75
|
+
attr_reader :open, :close
|
76
|
+
|
77
|
+
def to_s
|
78
|
+
[open, super, close].compact.join("\n")
|
79
|
+
end
|
80
|
+
|
81
|
+
def script(*args)
|
82
|
+
super(*merge_options(args, level: 1))
|
83
|
+
end
|
84
|
+
|
85
|
+
def cmd(code, *args)
|
86
|
+
super(code, *merge_options(args, level: 1))
|
87
|
+
end
|
88
|
+
|
89
|
+
def raw(code, *args)
|
90
|
+
super(code, *merge_options(args, level: 1))
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
class Conditional < Block
|
95
|
+
def initialize(condition, *args, &block)
|
96
|
+
args.unshift(args.last.delete(:then)) if args.last.is_a?(Hash) && args.last[:then]
|
97
|
+
unless args.last.delete(:raw_condition)
|
98
|
+
condition = "[[ #{condition} ]]"
|
99
|
+
end
|
100
|
+
super(*args, &block)
|
101
|
+
@open = Node.new("#{name} #{condition}; then", options)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
class If < Conditional
|
106
|
+
def close
|
107
|
+
Node.new('fi', options)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
class Elif < Conditional
|
112
|
+
end
|
113
|
+
|
114
|
+
class Else < Block
|
115
|
+
def open
|
116
|
+
@open = Node.new('else', options)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Perkins
|
2
|
+
module Build
|
3
|
+
module Shell
|
4
|
+
autoload :Dsl, 'perkins/build/shell/dsl'
|
5
|
+
autoload :Node, 'perkins/build/shell/node'
|
6
|
+
autoload :Cmd, 'perkins/build/shell/node'
|
7
|
+
autoload :Script, 'perkins/build/shell/node'
|
8
|
+
|
9
|
+
class InvalidParent < RuntimeError
|
10
|
+
def initialize(node, required, actual)
|
11
|
+
super("Node #{node.name} requires to be added to a #{required.name}, but is a #{actual.name}")
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Perkins
|
2
|
+
module Build
|
3
|
+
autoload :Data, 'perkins/build/data'
|
4
|
+
autoload :Script, 'perkins/build/script'
|
5
|
+
#autoload :Services, 'perkins/build/services'
|
6
|
+
autoload :Shell, 'perkins/build/shell'
|
7
|
+
|
8
|
+
HOME_DIR = '$HOME'
|
9
|
+
BUILD_DIR = File.join(HOME_DIR, 'build')
|
10
|
+
|
11
|
+
class << self
|
12
|
+
|
13
|
+
def script(config, options = {})
|
14
|
+
#config = config.deep_symbolize_keys
|
15
|
+
lang = (config.language || 'ruby').downcase.strip
|
16
|
+
const = by_lang(lang)
|
17
|
+
const.new(config, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def by_lang(lang)
|
21
|
+
name = lang.split('_').map { |w| w.capitalize }.join
|
22
|
+
Script.const_get(name, false) rescue Script::Ruby
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/perkins/cli.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require "thor"
|
2
|
+
require "thor/group"
|
3
|
+
require "pry"
|
4
|
+
#require "debugger"
|
5
|
+
module Perkins
|
6
|
+
class CLI < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
include Perkins::ThorUtils
|
9
|
+
|
10
|
+
STATUS_TYPES = {:success => 0,
|
11
|
+
:general_error => 1,
|
12
|
+
:not_supported => 3,
|
13
|
+
:not_found => 4,
|
14
|
+
:incorrect_usage => 64,
|
15
|
+
}
|
16
|
+
|
17
|
+
no_commands {
|
18
|
+
def cli_error(message, exit_status=nil)
|
19
|
+
$stderr.puts message
|
20
|
+
exit_status = STATUS_TYPES[exit_status] if exit_status.is_a?(Symbol)
|
21
|
+
exit(exit_status || 1)
|
22
|
+
end
|
23
|
+
}
|
24
|
+
|
25
|
+
### TODO: When these commands list grows big, we need to move them into a seperate commands.rb file
|
26
|
+
map %w(--version -v) => 'info'
|
27
|
+
desc "info", "information about Perkins::Client::Generator."
|
28
|
+
def info
|
29
|
+
say "Version #{::Perkins::VERSION}"
|
30
|
+
end
|
31
|
+
|
32
|
+
map %w(s) => 'server'
|
33
|
+
desc "server ", "run Perkins app"
|
34
|
+
method_option :host, :default => "localhost"
|
35
|
+
method_option :port, :default => 9292
|
36
|
+
method_option :e, :default => "development"
|
37
|
+
def server(config)
|
38
|
+
::Perkins::Server.start(config, options)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Perkins
|
2
|
+
class Commit
|
3
|
+
|
4
|
+
attr_reader :sha, :author, :created_at, :message
|
5
|
+
attr_accessor :branch
|
6
|
+
|
7
|
+
def initialize(sha, repo)
|
8
|
+
return if sha.nil?
|
9
|
+
@commit = repo.git.gcommit(sha)
|
10
|
+
@sha = sha
|
11
|
+
end
|
12
|
+
|
13
|
+
def author
|
14
|
+
@commit.author.name unless @commit.blank?
|
15
|
+
end
|
16
|
+
|
17
|
+
def email
|
18
|
+
@commit.author.email unless @commit.blank?
|
19
|
+
end
|
20
|
+
|
21
|
+
def created_at
|
22
|
+
@commit.author.date unless @commit.blank?
|
23
|
+
end
|
24
|
+
|
25
|
+
def message
|
26
|
+
@commit.message unless @commit.blank?
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Perkins
|
3
|
+
class AppProxy
|
4
|
+
APP_ATTRIBUTES = [:host, :port, :redis, :github_client_secret, :github_client_id ]
|
5
|
+
|
6
|
+
attr_accessor *APP_ATTRIBUTES
|
7
|
+
attr_reader :app
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@app = Application.new(options)
|
11
|
+
end
|
12
|
+
|
13
|
+
def server=(opts={})
|
14
|
+
opts.each{|k,v| Server.set(k,v)}
|
15
|
+
Server.set(:app , @app)
|
16
|
+
end
|
17
|
+
|
18
|
+
def config(&block)
|
19
|
+
@app.instance_eval &block
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/lib/perkins/dsl.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Perkins
|
3
|
+
def self.application(options = {}, &block)
|
4
|
+
app_proxy = Perkins::AppProxy.new(options)
|
5
|
+
if block.arity == 0
|
6
|
+
app_proxy.instance_eval &block
|
7
|
+
else
|
8
|
+
app_proxy.instance_exec(app_proxy, &block)
|
9
|
+
end
|
10
|
+
app_proxy.app
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
|
2
|
+
module Perkins
|
3
|
+
|
4
|
+
#this should be a daemon
|
5
|
+
#it will listen incoming messages
|
6
|
+
#it will run the propper repo with runner commands
|
7
|
+
#it will pass the message to other daemon to notify
|
8
|
+
#it will deploy ?
|
9
|
+
|
10
|
+
class Listener
|
11
|
+
|
12
|
+
attr_accessor :app
|
13
|
+
|
14
|
+
def run!
|
15
|
+
#chan't use the same $redis conn because it fails
|
16
|
+
#TODO: reconnect with same settings
|
17
|
+
redis_conn = Redis.new()
|
18
|
+
redis_conn.subscribe('perkins:commits') do |on|
|
19
|
+
on.message do |channel, msg|
|
20
|
+
exec_runner(channel, msg)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def exec_runner(channel, msg)
|
26
|
+
data = JSON.parse(msg)
|
27
|
+
puts "##{channel} - [#{data['name']}]: #{data['sha']}"
|
28
|
+
|
29
|
+
repo = Perkins::Repo.find(data["id"])
|
30
|
+
|
31
|
+
#Thread.new do
|
32
|
+
Worker.perform(repo, data['sha'], data['branch'] )
|
33
|
+
#end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|