perkins 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.ruby-version +1 -0
  4. data/.vagrant/machines/default/virtualbox/action_provision +1 -0
  5. data/.vagrant/machines/default/virtualbox/action_set_name +1 -0
  6. data/.vagrant/machines/default/virtualbox/id +1 -0
  7. data/Gemfile +0 -1
  8. data/README.md +11 -4
  9. data/Rakefile +3 -2
  10. data/TODO.md +2 -2
  11. data/Vagrantfile +53 -0
  12. data/db/migrate/20150220143050_add_status_fields_to_repos.rb +11 -0
  13. data/db/schema.rb +3 -1
  14. data/examples/Gemfile +4 -0
  15. data/examples/Gemfile.lock +164 -0
  16. data/examples/Procfile +4 -0
  17. data/examples/boot.rb +15 -0
  18. data/examples/config.ru +22 -0
  19. data/examples/database.yml +2 -2
  20. data/examples/sidekiq.yml +9 -0
  21. data/lib/core_ext/string/color.rb +22 -0
  22. data/lib/perkins/application.rb +27 -3
  23. data/lib/perkins/assets/images/error.gif +0 -0
  24. data/lib/perkins/assets/images/working.gif +0 -0
  25. data/lib/perkins/assets/javascripts/app.js +17 -1
  26. data/lib/perkins/assets/javascripts/config.js.coffee +14 -0
  27. data/lib/perkins/assets/javascripts/log_view.js.coffee +1 -2
  28. data/lib/perkins/assets/javascripts/perkings.js.coffee +129 -20
  29. data/lib/perkins/assets/javascripts/perkins/helpers.js.coffee +21 -0
  30. data/lib/perkins/assets/javascripts/perkins/m/models.js.coffee +50 -0
  31. data/lib/perkins/assets/javascripts/perkins/router.js.coffee +10 -0
  32. data/lib/perkins/assets/javascripts/perkins/v/dashboard.js.coffee +17 -0
  33. data/lib/perkins/assets/javascripts/perkins/v/err.js.coffee +12 -0
  34. data/lib/perkins/assets/javascripts/perkins/v/menu.js.coffee +10 -0
  35. data/lib/perkins/assets/javascripts/perkins/v/my_repos.js.coffee +41 -0
  36. data/lib/perkins/assets/javascripts/perkins/v/orgs.js.coffee +39 -0
  37. data/lib/perkins/assets/javascripts/perkins/v/profile.js.coffee +20 -0
  38. data/lib/perkins/assets/javascripts/perkins/v/repo.js.coffee +192 -0
  39. data/lib/perkins/assets/javascripts/perkins/v/sidebar.js.coffee +33 -0
  40. data/lib/perkins/assets/javascripts/templates/dashboard.hamlc +11 -0
  41. data/lib/perkins/assets/javascripts/templates/error.hamlc +22 -0
  42. data/lib/perkins/assets/javascripts/templates/menu.hamlc +18 -0
  43. data/lib/perkins/assets/javascripts/templates/org.hamlc +77 -0
  44. data/lib/perkins/assets/javascripts/templates/profile.hamlc +28 -0
  45. data/lib/perkins/assets/javascripts/templates/repo.hamlc +37 -0
  46. data/lib/perkins/assets/javascripts/templates/repos/build_row.hamlc +19 -0
  47. data/lib/perkins/assets/javascripts/templates/repos/builds.hamlc +25 -0
  48. data/lib/perkins/assets/javascripts/templates/repos/config.hamlc +77 -0
  49. data/lib/perkins/assets/javascripts/templates/repos/gb_repo.hamlc +31 -0
  50. data/lib/perkins/assets/javascripts/templates/repos/github.hamlc +7 -0
  51. data/lib/perkins/assets/javascripts/templates/repos/menu.hamlc +17 -0
  52. data/lib/perkins/assets/javascripts/templates/repos/report_detail.hamlc +53 -0
  53. data/lib/perkins/assets/javascripts/templates/sidebar.hamlc +14 -0
  54. data/lib/perkins/assets/javascripts/templates/sidebar_repo.hamlc +4 -0
  55. data/lib/perkins/assets/javascripts/vendor/backbone-min.js +2 -0
  56. data/lib/perkins/assets/javascripts/vendor/backbone.marionette.js +2891 -0
  57. data/lib/perkins/assets/javascripts/vendor/hamlcoffee.js.coffee.erb +138 -0
  58. data/lib/perkins/assets/javascripts/vendor/livequery.jquery.js +8 -0
  59. data/lib/perkins/assets/javascripts/vendor/log.js +1 -1
  60. data/lib/perkins/assets/javascripts/vendor/md5.js +207 -0
  61. data/lib/perkins/assets/javascripts/vendor/nprogress.js +476 -0
  62. data/lib/perkins/assets/javascripts/vendor/underscore.js +6 -0
  63. data/lib/perkins/assets/stylesheets/app.css +3 -0
  64. data/lib/perkins/assets/stylesheets/bootstrap-overrides.css.scss +13 -0
  65. data/lib/perkins/assets/stylesheets/styles.css.scss +30 -3
  66. data/lib/perkins/assets/stylesheets/vendor/nprogress.css +74 -0
  67. data/lib/perkins/assets.rb +42 -0
  68. data/lib/perkins/build/script/ruby.rb +1 -1
  69. data/lib/perkins/build_report.rb +13 -0
  70. data/lib/perkins/{worker.rb → build_worker.rb} +9 -5
  71. data/lib/perkins/cli.rb +4 -2
  72. data/lib/perkins/commit.rb +8 -1
  73. data/lib/perkins/git_loader_worker.rb +29 -0
  74. data/lib/perkins/repo.rb +23 -9
  75. data/lib/perkins/runner.rb +16 -25
  76. data/lib/perkins/server.rb +121 -116
  77. data/lib/perkins/version.rb +1 -1
  78. data/lib/perkins/views/builds.haml +0 -3
  79. data/lib/perkins/views/layout.haml +25 -36
  80. data/lib/perkins/views/menu.haml +1 -1
  81. data/lib/perkins/views/repos/github.haml +0 -31
  82. data/lib/perkins/views/repos/repo.haml +1 -1
  83. data/lib/perkins.rb +4 -2
  84. data/perkins.gemspec +5 -2
  85. data/spec/lib/repo_spec.rb +27 -6
  86. data/spec/lib/runner_spec.rb +1 -0
  87. data/spec/lib/server_spec.rb +6 -23
  88. data/spec/spec_helper.rb +14 -3
  89. metadata +160 -70
  90. data/examples/config.rb +0 -12
  91. data/examples/mongo.yml +0 -13
  92. data/lib/perkins/listener.rb +0 -38
  93. data/spec/lib/listener_spec.rb +0 -30
@@ -0,0 +1,42 @@
1
+ module Perkins
2
+ class Assets < Sinatra::Base
3
+
4
+ require "haml_coffee_assets"
5
+
6
+ configure do
7
+ set :assets, (Sprockets::Environment.new { |env|
8
+ env.append_path(settings.root + "/assets/images")
9
+ env.append_path(settings.root + "/assets/javascripts")
10
+ env.append_path(settings.root + "/assets/stylesheets")
11
+ # compress everything in production
12
+ if ENV["RACK_ENV"] == "production"
13
+ env.js_compressor = YUI::JavaScriptCompressor.new
14
+ env.css_compressor = YUI::CssCompressor.new
15
+ end
16
+ })
17
+ end
18
+
19
+ get "/assets/app.js" do
20
+ content_type("application/javascript")
21
+ settings.assets["app.js"]
22
+ end
23
+
24
+ get "/assets/app.css" do
25
+ content_type("text/css")
26
+ settings.assets["app.css"]
27
+ end
28
+
29
+ %w{jpg png gif}.each do |format|
30
+ get "/assets/:image.#{format}" do |image|
31
+ content_type("image/#{format}")
32
+ settings.assets["#{image}.#{format}"]
33
+ end
34
+ end
35
+
36
+ get "/assets/:image.svg" do |image|
37
+ content_type("image/svg+xml")
38
+ settings.assets["#{image}.svg"]
39
+ end
40
+
41
+ end
42
+ end
@@ -8,7 +8,7 @@ module Perkins
8
8
  }
9
9
 
10
10
  include Jdk
11
- include RVM
11
+ #include RVM
12
12
  include Bundler
13
13
 
14
14
  def announce
@@ -7,5 +7,18 @@ module Perkins
7
7
  @commit ||= Perkins::Commit.new(self.sha, self.repo)
8
8
  end
9
9
 
10
+ def as_json(options = {})
11
+ data = {}
12
+
13
+ unless fields = options[:only]
14
+ fields = [:id, :sha, :commit, :branch, :build_time,
15
+ :status, :duration, :build_time, :response]
16
+ end
17
+
18
+ fields.each { |k| data[k] = send(k) }
19
+
20
+ data
21
+ end
22
+
10
23
  end
11
24
  end
@@ -2,11 +2,13 @@ require 'net/http'
2
2
  require "uri"
3
3
 
4
4
  module Perkins
5
- class Worker
5
+ class BuildWorker
6
6
 
7
- #include Celluloid
7
+ include Sidekiq::Worker
8
8
 
9
- def self.perform(repo, sha, branch)
9
+ def perform(repo_id, sha, branch)
10
+ repo = Perkins::Repo.find(repo_id)
11
+ #it actually clone repo and instantiates git data
10
12
  repo.load_git
11
13
 
12
14
  return if repo.runner.blank?
@@ -22,9 +24,11 @@ module Perkins
22
24
  send_sse({repo: {id: repo.id, name: repo.name , status: "stop", report: report } })
23
25
  end
24
26
 
25
- def self.send_sse(msg)
27
+ def send_sse(msg)
28
+ url = "#{Perkins::Application.instance.sse_endpoint}/sse"
29
+ puts "send sse post to #{url} with msg: #{msg.to_json}".pink
26
30
  postData = Net::HTTP.post_form(
27
- URI.parse('http://localhost:3000/sse'),
31
+ URI.parse(url),
28
32
  {'msg'=> msg.to_json }
29
33
  )
30
34
  end
data/lib/perkins/cli.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require "thor"
2
2
  require "thor/group"
3
3
  require "pry"
4
- #require "debugger"
4
+ require "thin"
5
+
5
6
  module Perkins
6
7
  class CLI < Thor
7
8
  include Thor::Actions
@@ -31,10 +32,11 @@ module Perkins
31
32
 
32
33
  map %w(s) => 'server'
33
34
  desc "server ", "run Perkins app"
34
- method_option :host, :default => "localhost"
35
+ method_option :host, :default => "0.0.0.0"
35
36
  method_option :port, :default => 9292
36
37
  method_option :e, :default => "development"
37
38
  def server(config)
39
+ #::Perkins::Server.app = eval(File.open(options.config_file).read)
38
40
  ::Perkins::Server.start(config, options)
39
41
  end
40
42
 
@@ -1,7 +1,7 @@
1
1
  module Perkins
2
2
  class Commit
3
3
 
4
- attr_reader :sha, :author, :created_at, :message
4
+ attr_reader :sha
5
5
  attr_accessor :branch
6
6
 
7
7
  def initialize(sha, repo)
@@ -26,5 +26,12 @@ module Perkins
26
26
  @commit.message unless @commit.blank?
27
27
  end
28
28
 
29
+ def as_json(opts={})
30
+ data = {}
31
+ fields = [:author, :email, :created_at, :message, :sha]
32
+ fields.each{|f| data[f] = send(f)}
33
+ data
34
+ end
35
+
29
36
  end
30
37
  end
@@ -0,0 +1,29 @@
1
+ require 'net/http'
2
+ require "uri"
3
+
4
+ module Perkins
5
+ class GitLoaderWorker
6
+
7
+ include Sidekiq::Worker
8
+
9
+ def perform(repo_id)
10
+ repo = Perkins::Repo.find(repo_id)
11
+ #it actually clone repo and instantiates git data
12
+ send_sse({repo: {id: repo.id, name: repo.name , status: "downloading"} })
13
+
14
+ repo.load_git
15
+
16
+ send_sse({repo: {id: repo.id, name: repo.name , status: "downloaded" } })
17
+ end
18
+
19
+ def send_sse(msg)
20
+ url = "#{Perkins::Application.instance.sse_endpoint}/sse"
21
+ puts "send sse post to #{url} with msg: #{msg.to_json}".pink
22
+ postData = Net::HTTP.post_form(
23
+ URI.parse(url),
24
+ {'msg'=> msg.to_json }
25
+ )
26
+ end
27
+
28
+ end
29
+ end
data/lib/perkins/repo.rb CHANGED
@@ -40,7 +40,7 @@ module Perkins
40
40
  end
41
41
 
42
42
  def self.store_from_github(repo)
43
- repo
43
+ #repo
44
44
  repo.working_dir = DEFAULT_DIR #this should be configurable from app
45
45
  repo.cached = false
46
46
  repo.save
@@ -60,12 +60,20 @@ module Perkins
60
60
  clone_or_load
61
61
  end
62
62
 
63
+ def downloaded?
64
+ self.download_status.present? && self.download_status == "downloaded"
65
+ end
66
+
67
+ def downloading?
68
+ self.download_status.present? && self.download_status == "downloading"
69
+ end
70
+
63
71
  def clone_or_load
64
72
  if exists?
65
73
  open
66
74
  else
67
75
  ssh_url = self.github_data["ssh_url"]
68
- g = Git.clone(ssh_url, name, :path => working_dir)
76
+ Git.clone(ssh_url, name, :path => working_dir)
69
77
  open
70
78
  end
71
79
  end
@@ -73,11 +81,12 @@ module Perkins
73
81
  def open
74
82
  self.git = Git.open(local_path) # :log => Logger.new(STDOUT)
75
83
  build_runner_config(self.check_config_existence) if self.check_config_existence
84
+ self.update_column(:download_status, "downloaded")
76
85
  end
77
86
 
78
87
  def check_config_existence
79
88
  config = self.git.chdir{
80
- if File.exists?(".travis.yml")
89
+ if File.exist?(".travis.yml")
81
90
  config = Travis::Yaml.parse( File.open(".travis.yml").read )
82
91
  else
83
92
  config = Travis::Yaml.new
@@ -88,7 +97,7 @@ module Perkins
88
97
  end
89
98
 
90
99
  def exists?
91
- File.exists?(local_path)
100
+ File.exist?(local_path)
92
101
  end
93
102
 
94
103
  def local_path
@@ -121,16 +130,17 @@ module Perkins
121
130
 
122
131
  def add_commit(sha, branch)
123
132
  if runner_branch.include?(branch)
124
- @new_commit = Perkins::Commit.new(sha, self)
125
- @new_commit.branch = branch
126
- enqueue_commit(@new_commit)
133
+ #@new_commit = Perkins::Commit.new(sha, self)
134
+ #@new_commit.branch = branch
135
+ #enqueue_commit(@new_commit)
136
+ enqueue_commit(sha, branch)
127
137
  else
128
138
  puts "skipping commit from branch #{branch}"
129
139
  end
130
140
  end
131
141
 
132
- def enqueue_commit(commit)
133
- $redis.publish("commits", {id: self.id.to_s, name: self.name , sha: commit.sha, branch: commit.branch}.to_json)
142
+ def enqueue_commit(sha, branch)
143
+ BuildWorker.perform_async(self.id, sha, branch )
134
144
  end
135
145
 
136
146
  def http_url
@@ -140,6 +150,10 @@ module Perkins
140
150
  new_url
141
151
  end
142
152
 
153
+ def last_report_id
154
+ build_reports.last.id if build_reports.any?
155
+ end
156
+
143
157
  end
144
158
 
145
159
  end
@@ -8,8 +8,6 @@ module Perkins
8
8
  def exec(cmd)
9
9
  result = run_script(cmd)
10
10
  puts result
11
- #result = `bash #{cmd} 2>&1`.chomp
12
- #result = `go run #{ROOT_PATH + '/lib/perkins/build/runner.go'} -cmd="#{cmd}"`.chomp
13
11
  process_status = $?
14
12
 
15
13
  if successful_command?(process_status) || config_command_with_empty_value?(result,process_status)
@@ -19,11 +17,9 @@ module Perkins
19
17
  else
20
18
  @response = result
21
19
  @status = false
22
- #raise "command failed"
23
20
  end
24
21
  end
25
22
 
26
-
27
23
  def run_script(source)
28
24
  script = File.expand_path(
29
25
  "~/.perkins/.build/#{repo.name}/travis-build-#{sha}" #<< stages.join('-')
@@ -37,7 +33,6 @@ module Perkins
37
33
  end
38
34
 
39
35
  def run(sha)
40
-
41
36
  self.sha = sha
42
37
  start_build
43
38
  script = Perkins::Build::script(config, repo)
@@ -45,7 +40,7 @@ module Perkins
45
40
  repo.git.chdir do
46
41
  git_update(sha)
47
42
  set_build_stats do
48
- puts "perform build"
43
+ puts "perform build".green
49
44
  self.exec(sh)
50
45
  end
51
46
  end
@@ -54,15 +49,13 @@ module Perkins
54
49
  end
55
50
 
56
51
  def start_build
57
- #self.update_attributes(status: true)
58
- @running = true #self.status
59
- #$redis.set("#{repo.name}:running", true)
52
+ @running = true
53
+ @repo.update_column(:build_status, "started")
60
54
  end
61
55
 
62
56
  def stop_build
63
- #self.update_attributes(status: false)
64
- @running = false #self.status
65
- #redis.set("#{repo.name}:running", false)
57
+ @running = false
58
+ @repo.update_column(:build_status, "stopped")
66
59
  end
67
60
 
68
61
  def set_build_stats(&block)
@@ -75,7 +68,6 @@ module Perkins
75
68
  end
76
69
 
77
70
  def running?
78
- #repo.running?
79
71
  @running
80
72
  end
81
73
 
@@ -92,27 +84,26 @@ module Perkins
92
84
  end
93
85
 
94
86
  def git_update(branch)
95
- #`git fetch origin && git reset --hard #{sha}`
96
- puts "git fetch & reset to #{sha}"
87
+ puts "fetch repo & reset to sha #{sha}".green
97
88
  repo.git.fetch()
98
89
  repo.git.reset_hard(sha)
99
90
  end
100
91
 
92
+ #TODO: add a serialized commit in order to avoid
93
+ #Perkins::Commit initialization in every instantiation
101
94
  def to_report
102
- {id: SecureRandom.hex ,
103
- build_time: self.build_time ,
104
- duration: self.duration,
105
- response: self.response,
106
- status: self.status,
107
- sha: self.sha,
108
- branch: self.branch}
95
+ {
96
+ build_time: self.build_time,
97
+ duration: self.duration,
98
+ response: self.response,
99
+ status: self.status,
100
+ sha: self.sha,
101
+ branch: self.branch
102
+ }
109
103
  end
110
104
 
111
105
  def store_report
112
106
  r = Perkins::BuildReport.new(self.to_report)
113
- #return if report.keys.detect{|o| report[o].to_s == "" }
114
- #builds_to_save = get_builds << self.to_report
115
- #$redis.set("#{repo.name}:builds", builds_to_save.to_json )
116
107
  repo.build_reports << r
117
108
  end
118
109