perkins 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/.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
|