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