perkins 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.env.example +4 -0
  4. data/.gitignore +19 -0
  5. data/.pryrc +3 -0
  6. data/.rspec +2 -0
  7. data/Gemfile +18 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +71 -0
  10. data/Rakefile +28 -0
  11. data/TODO.md +4 -0
  12. data/bin/perkins +6 -0
  13. data/db/migrate/20150130143030_create_repo.rb +18 -0
  14. data/db/migrate/20150130143050_create_builds.rb +20 -0
  15. data/db/schema.rb +38 -0
  16. data/examples/config.rb +12 -0
  17. data/examples/database.yml +17 -0
  18. data/examples/mongo.yml +13 -0
  19. data/lib/core_ext/hash/compact.rb +8 -0
  20. data/lib/core_ext/hash/deep_merge.rb +15 -0
  21. data/lib/core_ext/hash/deep_symbolize_keys.rb +20 -0
  22. data/lib/core_ext/object/false.rb +5 -0
  23. data/lib/core_ext/string/indent.rb +5 -0
  24. data/lib/core_ext/string/unindent.rb +5 -0
  25. data/lib/perkins/.DS_Store +0 -0
  26. data/lib/perkins/application.rb +40 -0
  27. data/lib/perkins/assets/images/github.svg +4 -0
  28. data/lib/perkins/assets/images/spinner.svg +23 -0
  29. data/lib/perkins/assets/javascripts/app.js +9 -0
  30. data/lib/perkins/assets/javascripts/log_view.js.coffee +95 -0
  31. data/lib/perkins/assets/javascripts/perkings.js.coffee +40 -0
  32. data/lib/perkins/assets/javascripts/vendor/ansiparse.js +187 -0
  33. data/lib/perkins/assets/javascripts/vendor/jquery.timeago.js +189 -0
  34. data/lib/perkins/assets/javascripts/vendor/log.js +2 -0
  35. data/lib/perkins/assets/javascripts/vendor/minispade.js +55 -0
  36. data/lib/perkins/assets/stylesheets/app.css +2 -0
  37. data/lib/perkins/assets/stylesheets/log.css.scss +115 -0
  38. data/lib/perkins/assets/stylesheets/styles.css.scss +199 -0
  39. data/lib/perkins/auth/github.rb +181 -0
  40. data/lib/perkins/build/data/env.rb +84 -0
  41. data/lib/perkins/build/data/var.rb +60 -0
  42. data/lib/perkins/build/data.rb +167 -0
  43. data/lib/perkins/build/script/bundler.rb +76 -0
  44. data/lib/perkins/build/script/go.rb +100 -0
  45. data/lib/perkins/build/script/helpers.rb +39 -0
  46. data/lib/perkins/build/script/jdk.rb +43 -0
  47. data/lib/perkins/build/script/ruby.rb +31 -0
  48. data/lib/perkins/build/script/rvm.rb +73 -0
  49. data/lib/perkins/build/script/stages.rb +28 -0
  50. data/lib/perkins/build/script/templates/footer.sh +3 -0
  51. data/lib/perkins/build/script/templates/header.sh +201 -0
  52. data/lib/perkins/build/script/templates/xcode.sh +21 -0
  53. data/lib/perkins/build/script.rb +167 -0
  54. data/lib/perkins/build/shell/dsl.rb +104 -0
  55. data/lib/perkins/build/shell/node.rb +121 -0
  56. data/lib/perkins/build/shell.rb +16 -0
  57. data/lib/perkins/build.rb +27 -0
  58. data/lib/perkins/build_report.rb +11 -0
  59. data/lib/perkins/cli.rb +42 -0
  60. data/lib/perkins/commit.rb +30 -0
  61. data/lib/perkins/dsl/app_proxy.rb +23 -0
  62. data/lib/perkins/dsl.rb +12 -0
  63. data/lib/perkins/listener.rb +38 -0
  64. data/lib/perkins/logger.rb +12 -0
  65. data/lib/perkins/notifier.rb +5 -0
  66. data/lib/perkins/repo.rb +145 -0
  67. data/lib/perkins/runner.rb +124 -0
  68. data/lib/perkins/server.rb +314 -0
  69. data/lib/perkins/thor_utils.rb +79 -0
  70. data/lib/perkins/version.rb +3 -0
  71. data/lib/perkins/views/401.haml +1 -0
  72. data/lib/perkins/views/builds.haml +46 -0
  73. data/lib/perkins/views/index.haml +6 -0
  74. data/lib/perkins/views/layout.haml +53 -0
  75. data/lib/perkins/views/menu.haml +18 -0
  76. data/lib/perkins/views/orgs.haml +101 -0
  77. data/lib/perkins/views/profile.haml +31 -0
  78. data/lib/perkins/views/readme.md +20 -0
  79. data/lib/perkins/views/repos/config.haml +72 -0
  80. data/lib/perkins/views/repos/github.haml +76 -0
  81. data/lib/perkins/views/repos/menu.haml +17 -0
  82. data/lib/perkins/views/repos/repo.haml +64 -0
  83. data/lib/perkins/views/repos/spinner.haml +3 -0
  84. data/lib/perkins/webhooks/github.rb +12 -0
  85. data/lib/perkins/worker.rb +33 -0
  86. data/lib/perkins.rb +36 -0
  87. data/perkins.gemspec +52 -0
  88. data/spec/fixtures/.travis.yml +8 -0
  89. data/spec/fixtures/config.yml +6 -0
  90. data/spec/lib/build/build_spec.rb +58 -0
  91. data/spec/lib/commit_spec.rb +6 -0
  92. data/spec/lib/dsl_spec.rb +17 -0
  93. data/spec/lib/listener_spec.rb +30 -0
  94. data/spec/lib/repo_spec.rb +110 -0
  95. data/spec/lib/runner_spec.rb +76 -0
  96. data/spec/lib/server_spec.rb +108 -0
  97. data/spec/spec_helper.rb +67 -0
  98. data/spec/support/auth.rb +30 -0
  99. data/spec/support/github_api.rb +177 -0
  100. 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
@@ -0,0 +1,11 @@
1
+ module Perkins
2
+ class BuildReport < ActiveRecord::Base
3
+ belongs_to :repo
4
+
5
+ def commit
6
+ self.repo.load_git
7
+ @commit ||= Perkins::Commit.new(self.sha, self.repo)
8
+ end
9
+
10
+ end
11
+ end
@@ -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
@@ -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
@@ -0,0 +1,12 @@
1
+ module Perkins
2
+ class Logger
3
+
4
+ def self.report(msg)
5
+ $stdout.puts(msg.green.bold)
6
+ end
7
+
8
+ def self.error(msg)
9
+ $stderr.puts(msg.red.bold)
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+
2
+ module Perkins
3
+ class Notifier
4
+ end
5
+ end