perkins 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.ruby-version +1 -0
- data/.vagrant/machines/default/virtualbox/action_provision +1 -0
- data/.vagrant/machines/default/virtualbox/action_set_name +1 -0
- data/.vagrant/machines/default/virtualbox/id +1 -0
- data/Gemfile +0 -1
- data/README.md +11 -4
- data/Rakefile +3 -2
- data/TODO.md +2 -2
- data/Vagrantfile +53 -0
- data/db/migrate/20150220143050_add_status_fields_to_repos.rb +11 -0
- data/db/schema.rb +3 -1
- data/examples/Gemfile +4 -0
- data/examples/Gemfile.lock +164 -0
- data/examples/Procfile +4 -0
- data/examples/boot.rb +15 -0
- data/examples/config.ru +22 -0
- data/examples/database.yml +2 -2
- data/examples/sidekiq.yml +9 -0
- data/lib/core_ext/string/color.rb +22 -0
- data/lib/perkins/application.rb +27 -3
- data/lib/perkins/assets/images/error.gif +0 -0
- data/lib/perkins/assets/images/working.gif +0 -0
- data/lib/perkins/assets/javascripts/app.js +17 -1
- data/lib/perkins/assets/javascripts/config.js.coffee +14 -0
- data/lib/perkins/assets/javascripts/log_view.js.coffee +1 -2
- data/lib/perkins/assets/javascripts/perkings.js.coffee +129 -20
- data/lib/perkins/assets/javascripts/perkins/helpers.js.coffee +21 -0
- data/lib/perkins/assets/javascripts/perkins/m/models.js.coffee +50 -0
- data/lib/perkins/assets/javascripts/perkins/router.js.coffee +10 -0
- data/lib/perkins/assets/javascripts/perkins/v/dashboard.js.coffee +17 -0
- data/lib/perkins/assets/javascripts/perkins/v/err.js.coffee +12 -0
- data/lib/perkins/assets/javascripts/perkins/v/menu.js.coffee +10 -0
- data/lib/perkins/assets/javascripts/perkins/v/my_repos.js.coffee +41 -0
- data/lib/perkins/assets/javascripts/perkins/v/orgs.js.coffee +39 -0
- data/lib/perkins/assets/javascripts/perkins/v/profile.js.coffee +20 -0
- data/lib/perkins/assets/javascripts/perkins/v/repo.js.coffee +192 -0
- data/lib/perkins/assets/javascripts/perkins/v/sidebar.js.coffee +33 -0
- data/lib/perkins/assets/javascripts/templates/dashboard.hamlc +11 -0
- data/lib/perkins/assets/javascripts/templates/error.hamlc +22 -0
- data/lib/perkins/assets/javascripts/templates/menu.hamlc +18 -0
- data/lib/perkins/assets/javascripts/templates/org.hamlc +77 -0
- data/lib/perkins/assets/javascripts/templates/profile.hamlc +28 -0
- data/lib/perkins/assets/javascripts/templates/repo.hamlc +37 -0
- data/lib/perkins/assets/javascripts/templates/repos/build_row.hamlc +19 -0
- data/lib/perkins/assets/javascripts/templates/repos/builds.hamlc +25 -0
- data/lib/perkins/assets/javascripts/templates/repos/config.hamlc +77 -0
- data/lib/perkins/assets/javascripts/templates/repos/gb_repo.hamlc +31 -0
- data/lib/perkins/assets/javascripts/templates/repos/github.hamlc +7 -0
- data/lib/perkins/assets/javascripts/templates/repos/menu.hamlc +17 -0
- data/lib/perkins/assets/javascripts/templates/repos/report_detail.hamlc +53 -0
- data/lib/perkins/assets/javascripts/templates/sidebar.hamlc +14 -0
- data/lib/perkins/assets/javascripts/templates/sidebar_repo.hamlc +4 -0
- data/lib/perkins/assets/javascripts/vendor/backbone-min.js +2 -0
- data/lib/perkins/assets/javascripts/vendor/backbone.marionette.js +2891 -0
- data/lib/perkins/assets/javascripts/vendor/hamlcoffee.js.coffee.erb +138 -0
- data/lib/perkins/assets/javascripts/vendor/livequery.jquery.js +8 -0
- data/lib/perkins/assets/javascripts/vendor/log.js +1 -1
- data/lib/perkins/assets/javascripts/vendor/md5.js +207 -0
- data/lib/perkins/assets/javascripts/vendor/nprogress.js +476 -0
- data/lib/perkins/assets/javascripts/vendor/underscore.js +6 -0
- data/lib/perkins/assets/stylesheets/app.css +3 -0
- data/lib/perkins/assets/stylesheets/bootstrap-overrides.css.scss +13 -0
- data/lib/perkins/assets/stylesheets/styles.css.scss +30 -3
- data/lib/perkins/assets/stylesheets/vendor/nprogress.css +74 -0
- data/lib/perkins/assets.rb +42 -0
- data/lib/perkins/build/script/ruby.rb +1 -1
- data/lib/perkins/build_report.rb +13 -0
- data/lib/perkins/{worker.rb → build_worker.rb} +9 -5
- data/lib/perkins/cli.rb +4 -2
- data/lib/perkins/commit.rb +8 -1
- data/lib/perkins/git_loader_worker.rb +29 -0
- data/lib/perkins/repo.rb +23 -9
- data/lib/perkins/runner.rb +16 -25
- data/lib/perkins/server.rb +121 -116
- data/lib/perkins/version.rb +1 -1
- data/lib/perkins/views/builds.haml +0 -3
- data/lib/perkins/views/layout.haml +25 -36
- data/lib/perkins/views/menu.haml +1 -1
- data/lib/perkins/views/repos/github.haml +0 -31
- data/lib/perkins/views/repos/repo.haml +1 -1
- data/lib/perkins.rb +4 -2
- data/perkins.gemspec +5 -2
- data/spec/lib/repo_spec.rb +27 -6
- data/spec/lib/runner_spec.rb +1 -0
- data/spec/lib/server_spec.rb +6 -23
- data/spec/spec_helper.rb +14 -3
- metadata +160 -70
- data/examples/config.rb +0 -12
- data/examples/mongo.yml +0 -13
- data/lib/perkins/listener.rb +0 -38
- data/spec/lib/listener_spec.rb +0 -30
@@ -1,18 +1,13 @@
|
|
1
1
|
|
2
|
-
|
3
2
|
$(document).ready ()->
|
4
|
-
$("abbr.timeago").timeago()
|
5
|
-
|
6
3
|
|
7
|
-
|
8
|
-
|
9
|
-
#$(@).find(".build-response").toggleClass("hidden")
|
10
|
-
)
|
4
|
+
$("abbr.timeago").livequery ->
|
5
|
+
$(@).timeago()
|
11
6
|
|
12
7
|
#reading
|
13
8
|
es = new EventSource("/stream")
|
14
9
|
es.onmessage = (e) ->
|
15
|
-
console.log("
|
10
|
+
console.log("MESSAGE RECEIVED")
|
16
11
|
console.log(e.data)
|
17
12
|
a = JSON.parse(e.data)
|
18
13
|
|
@@ -20,21 +15,135 @@ $(document).ready ()->
|
|
20
15
|
$("#repo-#{a.repo.id} .fa-refresh").removeClass("fa-spin")
|
21
16
|
$(".repo-#{a.repo.id}-spinner.build-status").addClass("hidden")
|
22
17
|
if a.repo.status == "start"
|
23
|
-
debugger
|
24
18
|
$("#repo-#{a.repo.id} .fa-refresh").addClass("fa-spin")
|
25
19
|
$(".repo-#{a.repo.id}-spinner.build-status").removeClass("hidden")
|
26
20
|
|
27
|
-
|
21
|
+
#if repo.id is current repo then reload page
|
22
|
+
if current_repo && a.repo.id is current_repo.id && (a.repo.status is "stop" || a.repo.status is "downloaded" )
|
23
|
+
Backbone.history.loadUrl()
|
24
|
+
|
25
|
+
es.onerror = (e)->
|
26
|
+
console.log("error")
|
27
|
+
console.log(e)
|
28
|
+
|
29
|
+
NProgress.configure({ showSpinner: false })
|
30
|
+
|
31
|
+
$.ajaxSetup(
|
32
|
+
beforeSend: ()->
|
33
|
+
console.log "AJAX START!"
|
34
|
+
NProgress.start()
|
35
|
+
)
|
36
|
+
|
37
|
+
$( document ).ajaxStop ()->
|
38
|
+
console.log "AJAX STOP!"
|
39
|
+
NProgress.done()
|
40
|
+
|
41
|
+
#application
|
42
|
+
class Perkins.AppLayout extends Backbone.Marionette.Layout
|
43
|
+
template: "#perkins-layout"
|
44
|
+
|
45
|
+
regions:
|
46
|
+
menu: "#main-menu"
|
47
|
+
content: "#main-content"
|
48
|
+
sidebar: "#sidebar"
|
49
|
+
|
50
|
+
class Perkins.Views.ApplicationLayout extends Backbone.View
|
51
|
+
el: "body"
|
52
|
+
initialize: ->
|
53
|
+
console.log "Initializing"
|
54
|
+
@setupLayout()
|
55
|
+
@displayMenus()
|
56
|
+
@setupRouter()
|
57
|
+
@setupLinks()
|
58
|
+
@setupGlobalViews()
|
59
|
+
|
60
|
+
displayMenus: ->
|
61
|
+
@appLayout.menu.show( new Perkins.Views.Menu )
|
62
|
+
@appLayout.sidebar.show( new Perkins.Views.Sidebar )
|
63
|
+
|
64
|
+
getRepo: (login, name)->
|
65
|
+
@repo = new Perkins.Models.Repo()
|
66
|
+
@repo.set(name: "#{login}/#{name}")
|
67
|
+
|
68
|
+
setupRouter: ->
|
69
|
+
@app_router = new Perkins.Routers.main(trailingSlashIsSignificant: false)
|
70
|
+
|
71
|
+
@app_router.on 'route' , (opts)=>
|
72
|
+
console.log("any route")
|
73
|
+
|
74
|
+
@app_router.on 'route:getProfile', ()=>
|
75
|
+
console.log("on profile")
|
76
|
+
@.appLayout.content.show( new Perkins.Views.Profile )
|
77
|
+
|
78
|
+
@app_router.on 'route:getDashboard', (actions)=>
|
79
|
+
console.log("on dashboard")
|
80
|
+
@.appLayout.content.show( new Perkins.Views.Dashboard )
|
81
|
+
|
82
|
+
@app_router.on 'route:getRepo', (login, name)=>
|
83
|
+
console.log("get repo")
|
84
|
+
@getRepo(login , name)
|
85
|
+
@repo.fetch
|
86
|
+
success: =>
|
87
|
+
@.appLayout.content.show( new Perkins.Views.Repo(model: @repo) )
|
88
|
+
|
89
|
+
@app_router.on 'route:getRepoWithBuild', (login, name, id)=>
|
90
|
+
console.log("get repo")
|
91
|
+
@getRepo(login , name)
|
92
|
+
@id = id
|
93
|
+
@repo.fetch
|
94
|
+
success: =>
|
95
|
+
@.appLayout.content.show( new Perkins.Views.Repo(model: @repo, build_id: @id) )
|
96
|
+
|
97
|
+
@app_router.on "route:getRepoBuilds", (login, name)=>
|
98
|
+
console.log("repo builds")
|
99
|
+
@getRepo(login, name)
|
100
|
+
@repo.fetch
|
101
|
+
success: =>
|
102
|
+
@.appLayout.content.show( new Perkins.Views.RepoBuilds(model: @repo) )
|
103
|
+
|
104
|
+
@app_router.on "route:getRepoConfig", (login, name)=>
|
105
|
+
console.log("repo builds")
|
106
|
+
@getRepo(login, name)
|
107
|
+
@repo.fetch
|
108
|
+
success: =>
|
109
|
+
@.appLayout.content.show( new Perkins.Views.RepoConfig(model: @repo) )
|
110
|
+
|
111
|
+
@app_router.on "route:getOrg", (name)=>
|
112
|
+
@.appLayout.content.show( new Perkins.Views.Org(name: name) )
|
113
|
+
|
114
|
+
@app_router.on "route:getMyRepos", ()=>
|
115
|
+
console.log "MY REPOS"
|
116
|
+
@.appLayout.content.show( new Perkins.Views.MyRepos )
|
117
|
+
|
118
|
+
|
119
|
+
Backbone.history.start(pushState: true)
|
120
|
+
|
121
|
+
setupLinks: ->
|
122
|
+
# Globally capture clicks. If they are internal and not in the pass
|
123
|
+
# through list, route them through Backbone's navigate method.
|
124
|
+
_this = this
|
125
|
+
|
126
|
+
$("body").on "click", "a[href^='/']", (event) ->
|
127
|
+
target = $(event.currentTarget)
|
128
|
+
href = target.attr('href')
|
129
|
+
|
130
|
+
# chain 'or's for other black list routes
|
131
|
+
passThrough = href.indexOf('logout') >= 0 or $(event.currentTarget).data("remote") or $(event.currentTarget).data("dont-push")
|
132
|
+
|
133
|
+
# Allow shift+click for new tabs, etc.
|
134
|
+
if !passThrough && !event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey
|
135
|
+
|
136
|
+
# Remove leading slashes and hash bangs (backward compatablility)
|
137
|
+
url = href.replace(/^\//,'').replace('\#\/','')
|
138
|
+
|
139
|
+
window.data_navigation = target.data("navigation")
|
140
|
+
# Instruct Backbone to trigger routing events
|
141
|
+
_this.app_router.navigate url, { trigger: true }
|
28
142
|
|
29
|
-
|
30
|
-
log_view.render()
|
31
|
-
#log_view.reset()
|
143
|
+
return false
|
32
144
|
|
33
|
-
|
34
|
-
|
35
|
-
num = $(this.parentNode).prevAll('p').length + 1
|
36
|
-
url = window.location + ''
|
37
|
-
$(this).attr('href', url.replace(/#L\d+|(?=\?)|$/, '#L' + num))
|
145
|
+
setupLayout: ->
|
146
|
+
@appLayout = new Perkins.AppLayout
|
38
147
|
|
39
|
-
|
40
|
-
|
148
|
+
setupGlobalViews: ->
|
149
|
+
window.error_view = new Perkins.Views.Err
|
@@ -0,0 +1,21 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
Perkins.Helpers.gravatar_url = (email, size) ->
|
4
|
+
gravatar_id = MD5(email)
|
5
|
+
"http://gravatar.com/avatar/#{gravatar_id}.png?s=#{size}"
|
6
|
+
|
7
|
+
Perkins.Helpers.commit_url = (repo, sha) ->
|
8
|
+
"#{repo.http_url}/commit/#{sha}"
|
9
|
+
|
10
|
+
Perkins.Helpers.status_label = (status)->
|
11
|
+
label = if status == true then "success" else "default"
|
12
|
+
msg = if status == true then "passed" else "error"
|
13
|
+
"<span class='label label-#{label}'>build | #{msg}</span>"
|
14
|
+
|
15
|
+
Perkins.Helpers.status_class = (status)->
|
16
|
+
if status == true then "glyphicon glyphicon-ok" else "glyphicon glyphicon-remove"
|
17
|
+
|
18
|
+
Perkins.Helpers.round = (int, decimals=2)->
|
19
|
+
#Math.round(int * 100) / 100
|
20
|
+
#+int.toFixed(2);
|
21
|
+
parseFloat(int).toFixed(decimals)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
class Perkins.Models.Profile extends Backbone.Model
|
2
|
+
url: ()->
|
3
|
+
"/me"
|
4
|
+
|
5
|
+
class Perkins.Models.Repo extends Backbone.Model
|
6
|
+
url: ()->
|
7
|
+
if @.get('name')
|
8
|
+
"/repos/#{@.get('name')}"
|
9
|
+
else
|
10
|
+
"/repos"
|
11
|
+
|
12
|
+
class Perkins.Collections.Repos extends Backbone.Collection
|
13
|
+
model: Perkins.Models.Repo
|
14
|
+
url: ->
|
15
|
+
"/repos"
|
16
|
+
|
17
|
+
class Perkins.Models.BuildReport extends Backbone.Model
|
18
|
+
initialize: (opts={})->
|
19
|
+
@repo = opts.repo
|
20
|
+
|
21
|
+
url: ->
|
22
|
+
"/repos/#{@repo.get('name')}/builds/#{@id}"
|
23
|
+
|
24
|
+
restart: ->
|
25
|
+
@fetch(url: @url() + "/restart")
|
26
|
+
|
27
|
+
class Perkins.Collections.BuildReports extends Backbone.Collection
|
28
|
+
model: Perkins.Models.BuildReport
|
29
|
+
|
30
|
+
initialize: (opts={})->
|
31
|
+
@repo = opts.repo
|
32
|
+
|
33
|
+
url: ->
|
34
|
+
"/repos/#{@repo.get('name')}/builds"
|
35
|
+
|
36
|
+
class Perkins.Models.RepoHook extends Backbone.Model
|
37
|
+
initialize: (opts={})->
|
38
|
+
@repo = opts.repo
|
39
|
+
|
40
|
+
url: ->
|
41
|
+
"/repos/#{@repo.get('name')}/config"
|
42
|
+
|
43
|
+
class Perkins.Models.Org extends Backbone.Model
|
44
|
+
url: ->
|
45
|
+
"/orgs/#{@.get('name')}"
|
46
|
+
|
47
|
+
class Perkins.Collections.Orgs extends Backbone.Collection
|
48
|
+
model: Perkins.Models.Org
|
49
|
+
url: ->
|
50
|
+
"/orgs"
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Perkins.Routers.main extends Backbone.Router
|
2
|
+
routes:
|
3
|
+
"" : "getDashboard"
|
4
|
+
"me": "getProfile"
|
5
|
+
"repos/:login/:name": "getRepo"
|
6
|
+
"repos/:login/:name/builds/:id": "getRepoWithBuild"
|
7
|
+
"repos/:login/:name/builds": "getRepoBuilds"
|
8
|
+
"repos/:login/:name/config": "getRepoConfig"
|
9
|
+
"orgs/:name": "getOrg"
|
10
|
+
"myrepos": "getMyRepos"
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Perkins.Views.Dashboard extends Backbone.View
|
2
|
+
el: "#main-content"
|
3
|
+
|
4
|
+
initialize: ->
|
5
|
+
|
6
|
+
template: ->
|
7
|
+
JST["dashboard"]()
|
8
|
+
|
9
|
+
render: ()->
|
10
|
+
$(@el).html(@template())
|
11
|
+
|
12
|
+
close: ()->
|
13
|
+
$(@el).html("")
|
14
|
+
console.log "CLOSED VIEW CALLED"
|
15
|
+
@.stopListening()
|
16
|
+
@.undelegateEvents()
|
17
|
+
@.unbind()
|
@@ -0,0 +1,41 @@
|
|
1
|
+
class Perkins.Views.MyRepos extends Backbone.View
|
2
|
+
el: "#main-content"
|
3
|
+
|
4
|
+
events:
|
5
|
+
"click .add-repo" : "addRepo"
|
6
|
+
|
7
|
+
initialize: (opts={})->
|
8
|
+
@model = new Backbone.Model(name: opts.name)
|
9
|
+
|
10
|
+
template: ->
|
11
|
+
JST["repos/github"](@model.toJSON())
|
12
|
+
|
13
|
+
render: ()->
|
14
|
+
@model.fetch
|
15
|
+
url: "/myrepos"
|
16
|
+
success: =>
|
17
|
+
$(@el).html(@template())
|
18
|
+
|
19
|
+
#TODO: use a collection view and decouple
|
20
|
+
addRepo: (ev)->
|
21
|
+
target = $(ev.currentTarget)
|
22
|
+
target.text("adding...")
|
23
|
+
target.addClass("btn-diabled")
|
24
|
+
repo_id = target.data('gb-id')
|
25
|
+
url = "/repos/add/#{repo_id}"
|
26
|
+
|
27
|
+
#add repo & refresh sidebar on success.
|
28
|
+
$.ajax
|
29
|
+
url: url
|
30
|
+
success: ->
|
31
|
+
sidebar = Applayout.appLayout.sidebar.currentView
|
32
|
+
sidebar.repos.reset()
|
33
|
+
sidebar.repos.fetch()
|
34
|
+
false
|
35
|
+
|
36
|
+
close: ()->
|
37
|
+
$(@el).html("")
|
38
|
+
console.log "CLOSED VIEW CALLED"
|
39
|
+
@.stopListening()
|
40
|
+
@.undelegateEvents()
|
41
|
+
@.unbind()
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Perkins.Views.Org extends Backbone.View
|
2
|
+
el: "#main-content"
|
3
|
+
|
4
|
+
events:
|
5
|
+
"click .add-repo" : "addRepo"
|
6
|
+
|
7
|
+
initialize: (opts={})->
|
8
|
+
@model = new Perkins.Models.Org(name: opts.name)
|
9
|
+
|
10
|
+
template: ->
|
11
|
+
JST["org"](@model.toJSON())
|
12
|
+
|
13
|
+
render: ()->
|
14
|
+
@model.fetch
|
15
|
+
success: =>
|
16
|
+
$(@el).html(@template())
|
17
|
+
|
18
|
+
addRepo: (ev)->
|
19
|
+
target = $(ev.currentTarget)
|
20
|
+
target.text("adding...")
|
21
|
+
target.addClass("btn-diabled")
|
22
|
+
repo_id = target.data('gb-id')
|
23
|
+
url = "/repos/add/#{repo_id}"
|
24
|
+
|
25
|
+
#add repo & refresh sidebar on success.
|
26
|
+
$.ajax
|
27
|
+
url: url
|
28
|
+
success: ->
|
29
|
+
sidebar = Applayout.appLayout.sidebar.currentView
|
30
|
+
sidebar.repos.reset()
|
31
|
+
sidebar.repos.fetch()
|
32
|
+
false
|
33
|
+
|
34
|
+
close: ()->
|
35
|
+
$(@el).html("")
|
36
|
+
console.log "CLOSED VIEW CALLED"
|
37
|
+
@.stopListening()
|
38
|
+
@.undelegateEvents()
|
39
|
+
@.unbind()
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Perkins.Views.Profile extends Backbone.View
|
2
|
+
el: "#main-content"
|
3
|
+
|
4
|
+
initialize: ->
|
5
|
+
@model = new Perkins.Models.Profile
|
6
|
+
|
7
|
+
template: ->
|
8
|
+
JST["profile"](@model.toJSON())
|
9
|
+
|
10
|
+
render: ()->
|
11
|
+
@model.fetch
|
12
|
+
success: =>
|
13
|
+
$(@el).html(@template())
|
14
|
+
|
15
|
+
close: ()->
|
16
|
+
$(@el).html("")
|
17
|
+
console.log "CLOSED VIEW CALLED"
|
18
|
+
@.stopListening()
|
19
|
+
@.undelegateEvents()
|
20
|
+
@.unbind()
|
@@ -0,0 +1,192 @@
|
|
1
|
+
#SHOW REPO
|
2
|
+
class Perkins.Views.Repo extends Backbone.View
|
3
|
+
el: "#main-content"
|
4
|
+
|
5
|
+
events:
|
6
|
+
'mouseenter #log a' : "replaceUri"
|
7
|
+
'click #log .fold' : "toggleFold"
|
8
|
+
'click #restart-build-btn' : "restartBuild"
|
9
|
+
'click .run-commit': "runCommit"
|
10
|
+
|
11
|
+
initialize: (opts)->
|
12
|
+
@model = opts.model
|
13
|
+
|
14
|
+
if opts.build_id
|
15
|
+
@build = new Perkins.Models.BuildReport({id: opts.build_id, repo: @model})
|
16
|
+
else if @model.get('last_report_id')
|
17
|
+
@build = new Perkins.Models.BuildReport({id: @model.get('last_report_id'), repo: @model})
|
18
|
+
|
19
|
+
@listenTo(@build, "change", @renderBuildReport) if @build
|
20
|
+
@listenTo(@model, "change:build_status", @handleSpinnerBtn)
|
21
|
+
|
22
|
+
template: ()->
|
23
|
+
JST["repo"](@model.toJSON())
|
24
|
+
|
25
|
+
replaceUri: (ev)->
|
26
|
+
console.log ev
|
27
|
+
t = ev.currentTarget
|
28
|
+
num = $(t.parentNode).prevAll('p').length + 1
|
29
|
+
url = window.location + ''
|
30
|
+
$(t).attr('href', url.replace(/#L\d+|(?=\?)|$/, '#L' + num))
|
31
|
+
|
32
|
+
handleSpinnerBtn: ->
|
33
|
+
if @model.get('build_status') is "started"
|
34
|
+
$(".fa-refresh").addClass("fa-spin")
|
35
|
+
else if @model.get('build_status') is "stopped"
|
36
|
+
$(".fa-refresh").removeClass("fa-spin")
|
37
|
+
|
38
|
+
toggleFold: (ev)->
|
39
|
+
console.log ev
|
40
|
+
$(ev.currentTarget).toggleClass('open')
|
41
|
+
|
42
|
+
render: ->
|
43
|
+
console.log("render repo")
|
44
|
+
$(@el).html(@template())
|
45
|
+
@handleSpinnerBtn()
|
46
|
+
|
47
|
+
if @build
|
48
|
+
@build_detail = new Perkins.Views.BuildDetail( repo: @model, build: @build )
|
49
|
+
@build.fetch()
|
50
|
+
@displayBadge()
|
51
|
+
|
52
|
+
displayBadge: ->
|
53
|
+
name = @model.get('name')
|
54
|
+
url = "#{window.location.origin}/badge?repo=#{name}"
|
55
|
+
badge = "<a href='#{url}' target='blank'><img src='#{url}' alt='badge'></a>"
|
56
|
+
$('#badge-placeholder').html(badge)
|
57
|
+
|
58
|
+
renderBuildReport: ->
|
59
|
+
@build_detail.render()
|
60
|
+
|
61
|
+
restartBuild: (ev)->
|
62
|
+
return if $(ev.currentTarget).find("i").hasClass("fa-spin")
|
63
|
+
@build_detail.restart()
|
64
|
+
|
65
|
+
runCommit: ->
|
66
|
+
url = "/repos/#{@model.get('name')}/run_commit"
|
67
|
+
$.ajax
|
68
|
+
url: url
|
69
|
+
beforeSend: ->
|
70
|
+
$(".no-build").text("running build")
|
71
|
+
$(".run-commit").addClass("hide")
|
72
|
+
|
73
|
+
error: (err)->
|
74
|
+
$(".no-build").text("oops! we received status #{err.status}")
|
75
|
+
$(".run-commit").text("try again").removeClass("hide")
|
76
|
+
success: =>
|
77
|
+
$(".no-build").text("running build")
|
78
|
+
|
79
|
+
false
|
80
|
+
|
81
|
+
close: ()->
|
82
|
+
$(@el).html("")
|
83
|
+
console.log "CLOSED VIEW CALLED"
|
84
|
+
@.stopListening()
|
85
|
+
@.undelegateEvents()
|
86
|
+
@.unbind()
|
87
|
+
|
88
|
+
#repo build detail
|
89
|
+
class Perkins.Views.BuildDetail extends Backbone.View
|
90
|
+
|
91
|
+
el: "#build-report-container"
|
92
|
+
|
93
|
+
initialize: (opts={})->
|
94
|
+
@repo = opts.repo
|
95
|
+
window.current_repo = @repo
|
96
|
+
@build = opts.build
|
97
|
+
|
98
|
+
template: ->
|
99
|
+
JST["repos/report_detail"]({repo: @repo.toJSON(), build: @build.toJSON()})
|
100
|
+
|
101
|
+
render: ->
|
102
|
+
$(@el).html(@template())
|
103
|
+
window.log_view = new LogView(el: "#log")
|
104
|
+
log_view.render()
|
105
|
+
@displayRestartBuildBtn()
|
106
|
+
$("#no-build-warning").addClass("hide")
|
107
|
+
|
108
|
+
displayRestartBuildBtn: ->
|
109
|
+
$("#restart-build-btn").removeClass("hide")
|
110
|
+
#url = "/repos/#{@repo.get('name')}/builds/#{@build.id}/restart"
|
111
|
+
#$("#restart-build-btn").find("a").attr("href", url )
|
112
|
+
|
113
|
+
restart: ->
|
114
|
+
$("#restart-build-btn").find("i").addClass("fa-spin")
|
115
|
+
@build.restart()
|
116
|
+
false
|
117
|
+
|
118
|
+
close: ()->
|
119
|
+
$(@el).html("")
|
120
|
+
console.log "CLOSED VIEW CALLED"
|
121
|
+
@.stopListening()
|
122
|
+
@.undelegateEvents()
|
123
|
+
@.unbind()
|
124
|
+
|
125
|
+
#REPO BUILDS
|
126
|
+
class Perkins.Views.RepoBuilds extends Backbone.View
|
127
|
+
initialize: (opts={})->
|
128
|
+
@repo = opts.model
|
129
|
+
window.current_repo = @repo
|
130
|
+
@builds = new Perkins.Collections.BuildReports(repo: @repo)
|
131
|
+
|
132
|
+
el: "#main-content"
|
133
|
+
|
134
|
+
template: ->
|
135
|
+
JST["repos/builds"]({repo: @repo.toJSON() , builds: @builds})
|
136
|
+
|
137
|
+
render: ->
|
138
|
+
console.log("render repo builds")
|
139
|
+
$(@el).html(@template())
|
140
|
+
@builds_view = new Perkins.Views.RepoBuildCollection(collection: @builds)
|
141
|
+
@builds.fetch()
|
142
|
+
|
143
|
+
close: ()->
|
144
|
+
$(@el).html("")
|
145
|
+
console.log "CLOSED VIEW CALLED"
|
146
|
+
@.stopListening()
|
147
|
+
@.undelegateEvents()
|
148
|
+
@.unbind()
|
149
|
+
|
150
|
+
class Perkins.Views.RepoBuildItem extends Backbone.Marionette.ItemView
|
151
|
+
|
152
|
+
tagName: "tr"
|
153
|
+
|
154
|
+
template: (serialized_model) ->
|
155
|
+
JST['repos/build_row'](serialized_model)
|
156
|
+
|
157
|
+
class Perkins.Views.RepoBuildCollection extends Backbone.Marionette.CollectionView
|
158
|
+
itemView: Perkins.Views.RepoBuildItem
|
159
|
+
el: "#repo-builds"
|
160
|
+
|
161
|
+
#REPO CONFIG
|
162
|
+
|
163
|
+
class Perkins.Views.RepoConfig extends Backbone.View
|
164
|
+
initialize: (opts={})->
|
165
|
+
@repo = opts.model
|
166
|
+
window.current_repo = @repo
|
167
|
+
@hook = new Perkins.Models.RepoHook(repo: @repo)
|
168
|
+
|
169
|
+
@listenTo(@hook, "error", @defaultErrorHandler)
|
170
|
+
|
171
|
+
|
172
|
+
el: "#main-content"
|
173
|
+
|
174
|
+
template: ->
|
175
|
+
JST["repos/config"]({repo: @model.toJSON(), hook: @hook.toJSON() })
|
176
|
+
|
177
|
+
render: ->
|
178
|
+
console.log("render repo builds")
|
179
|
+
@hook.fetch
|
180
|
+
success: =>
|
181
|
+
$(@el).html(@template())
|
182
|
+
|
183
|
+
close: ()->
|
184
|
+
$(@el).html("")
|
185
|
+
console.log "CLOSED VIEW CALLED"
|
186
|
+
@.stopListening()
|
187
|
+
@.undelegateEvents()
|
188
|
+
@.unbind()
|
189
|
+
|
190
|
+
defaultErrorHandler: (model, error)=>
|
191
|
+
unless error.status < 500
|
192
|
+
error_view.render(status: error.status)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Perkins.Views.Sidebar extends Backbone.View
|
2
|
+
el: "#sidebar"
|
3
|
+
|
4
|
+
initialize: ->
|
5
|
+
@repos = new Perkins.Collections.Repos
|
6
|
+
@listenTo(@repos, "sync", @renderReposList)
|
7
|
+
|
8
|
+
template: ->
|
9
|
+
JST["sidebar"]()
|
10
|
+
|
11
|
+
render: ->
|
12
|
+
$(@el).html(@template())
|
13
|
+
@repos.fetch()
|
14
|
+
|
15
|
+
renderReposList: ->
|
16
|
+
console.log "sync"
|
17
|
+
@repos_list ||= new Perkins.Views.SidebarRepoCollection(collection: @repos)
|
18
|
+
@repos_list.render()
|
19
|
+
|
20
|
+
class Perkins.Views.SidebarRepoItem extends Backbone.Marionette.ItemView
|
21
|
+
|
22
|
+
tagName: "li"
|
23
|
+
|
24
|
+
#events:
|
25
|
+
|
26
|
+
template: (serialized_model) ->
|
27
|
+
JST['sidebar_repo'](serialized_model)
|
28
|
+
|
29
|
+
class Perkins.Views.SidebarRepoCollection extends Backbone.Marionette.CollectionView
|
30
|
+
itemView: Perkins.Views.SidebarRepoItem
|
31
|
+
el: "#sidebar-repos"
|
32
|
+
|
33
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
.error
|
2
|
+
|
3
|
+
-#%i.fa.fa-5x.fa-exclamation-triangle
|
4
|
+
|
5
|
+
%h2 We found an error loading this page.
|
6
|
+
|
7
|
+
|
8
|
+
- if current_repo
|
9
|
+
- url = "#{current_repo.get('url')}/settings"
|
10
|
+
- else
|
11
|
+
- url = "/"
|
12
|
+
|
13
|
+
%p
|
14
|
+
%img{src: "/assets/error.gif"}
|
15
|
+
|
16
|
+
%hr
|
17
|
+
|
18
|
+
- if url
|
19
|
+
%a.btn.btn-primary{href: "#{url}", data: {"dont-push": "true"}, target: "blank" }
|
20
|
+
Check your permissions on #{current_repo.get('github_data').name} and try again.
|
21
|
+
|
22
|
+
%h3 error status: #{@status}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
%nav#main-menu.navbar.navbar-fixed-top{role:"navigation"}
|
2
|
+
.container
|
3
|
+
.navbar-header
|
4
|
+
%button.navbar-toggle{"data-target" => ".nav-collapse", "data-toggle" => "collapse", :type => "button"}
|
5
|
+
%span.sr-only
|
6
|
+
%span.icon-bar
|
7
|
+
%span.icon-bar
|
8
|
+
%span.icon-bar
|
9
|
+
.title
|
10
|
+
%a.navbar-brand{:href => "/#"} Perkins
|
11
|
+
|
12
|
+
.navbar-inner.pull-right
|
13
|
+
.nav-collapse
|
14
|
+
%ul.nav.navbar-nav
|
15
|
+
%li
|
16
|
+
%a{:href => "/"} Home
|
17
|
+
%li
|
18
|
+
%a{:href => "/logout", data: {"dont-push"=> "true"}} Logout
|