perkins 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 65cad89e186bf43bf4f625869e5ef7012d1bd142
|
4
|
+
data.tar.gz: e30c3e0929a4c1a2607f774faa560bf85905c651
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 4c16b152d0eafe6dbd59e69f2ac50751f11c7e046dae46b16b3423e838382817d20edf1a52bf095633b7c8322b24bd3a82a51c11c62a8f480fe921bf755d3cc7
|
7
|
+
data.tar.gz: 48ab52ccd96358d3e98a34df3c7bc53b22509a6e25b69f2b74763b2ff4ad64cdd26d455e4624801bcd49cbcc8a053194d02f73c9bb7530d164c22805b5294c3d
|
data/.DS_Store
ADDED
Binary file
|
data/.env.example
ADDED
data/.gitignore
ADDED
data/.pryrc
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in perkins.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
gem "debugger"
|
7
|
+
gem "pry"
|
8
|
+
|
9
|
+
group :test do
|
10
|
+
gem "rspec"
|
11
|
+
gem "rspec-mocks"
|
12
|
+
gem "rack-test"
|
13
|
+
gem "vcr"
|
14
|
+
gem "webmock"
|
15
|
+
gem 'dotenv-rails'
|
16
|
+
gem 'database_cleaner'
|
17
|
+
end
|
18
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 miguel michelson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
# Perkins
|
2
|
+
|
3
|
+
### A travis compatible standalone CI solution for ruby
|
4
|
+
|
5
|
+
Behind the scenes perkins uses a slightly modified version of *travis-build* library and uses *Travis-yaml* gem to parse the .travis.yml files on existing repos. Also it integrates the Log.js library to display the build log the same way Travis does.
|
6
|
+
|
7
|
+
Said that, big kudos to Travis team for developing such an art piece and save us months of work to develop those components
|
8
|
+
|
9
|
+
## Why not use Travis open source app ?
|
10
|
+
|
11
|
+
Travis code is undoubtedly a piece of art, but at the same time is a complex application, made of several components, at least 8, with a service-oriented architecture. That's great! but for a small team like mine we can't afford manage as many applications for a single task, so we prefer to use a monolithic, lightweight solution to run our specs, in a Travis compatible way, yay!
|
12
|
+
|
13
|
+
### Status:
|
14
|
+
|
15
|
+
Perkins is at experimental fase, use at your own risk.
|
16
|
+
|
17
|
+
## Features:
|
18
|
+
|
19
|
+
+ Github webhook receiver.
|
20
|
+
+ Github user & orgs repo selector.
|
21
|
+
+ .travis.yml detection
|
22
|
+
+ Build for ruby (supports bundler and rvm or chruby)
|
23
|
+
+ Build for Go.
|
24
|
+
+ Addition of more languages should be trivial thanks to travis-build.
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
`gem install perkins`
|
29
|
+
|
30
|
+
## Usage
|
31
|
+
|
32
|
+
`perkins server config.rb --port=3000`
|
33
|
+
|
34
|
+
or
|
35
|
+
|
36
|
+
`bundle exec perkins server config.rb --port=3000`
|
37
|
+
|
38
|
+
## Configuration
|
39
|
+
|
40
|
+
configuration file for perkins to run.
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Perkins.application() do |app|
|
44
|
+
|
45
|
+
config do |c|
|
46
|
+
c.redis = {host: "localhost"}
|
47
|
+
c.github_client_id = ENV['GITHUB_CLIENT_ID']
|
48
|
+
c.github_client_secret = ENV['GITHUB_SECRET']
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
```
|
53
|
+
|
54
|
+
## Webhooks
|
55
|
+
|
56
|
+
To set the webhook for a repo you can go to github repo admin or visit a perkins repo on `youapp.com/repos/my/repo/config`
|
57
|
+
|
58
|
+
## Travis.yml
|
59
|
+
|
60
|
+
When Perkins runs a build it will search for a travis.yml file on the root of your repository, so existing repos with that file will just work.
|
61
|
+
|
62
|
+
You can read more info about build config at:
|
63
|
+
http://docs.travis-ci.com/user/build-configuration/
|
64
|
+
|
65
|
+
## Contributing
|
66
|
+
|
67
|
+
1. Fork it ( https://github.com/michelson/perkins/fork )
|
68
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
69
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
70
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
71
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
require 'rspec/core/rake_task'
|
4
|
+
|
5
|
+
require "sinatra/activerecord/rake"
|
6
|
+
|
7
|
+
require "pry"
|
8
|
+
|
9
|
+
require "perkins"
|
10
|
+
|
11
|
+
desc 'Default: run unit specs.'
|
12
|
+
task :default => :spec
|
13
|
+
|
14
|
+
desc 'Test perkins.'
|
15
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
16
|
+
t.pattern = FileList['spec/**/*_spec.rb']
|
17
|
+
end
|
18
|
+
|
19
|
+
#usage: PERKINS_CONFIG=./examples/config.rb RACK_ENV=development rake db:migrate --trace
|
20
|
+
namespace :db do
|
21
|
+
task :load_config do
|
22
|
+
ENV['RACK_ENV'] = ENV['RACK_ENV'].present? ? ENV['RACK_ENV'] : "development"
|
23
|
+
config_file = ENV["PERKINS_CONFIG"]
|
24
|
+
app = eval(File.open(config_file).read)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
data/TODO.md
ADDED
data/bin/perkins
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateRepo < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table "repos", :force => true do |t|
|
4
|
+
t.column :url, :string
|
5
|
+
t.column :name, :string
|
6
|
+
t.column :working_dir, :string
|
7
|
+
t.column :branch, :string
|
8
|
+
t.column :gb_id, :integer
|
9
|
+
t.column :github_data, :text
|
10
|
+
t.column :cached, :boolean
|
11
|
+
end
|
12
|
+
add_index :repos, :gb_id, :unique => true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table "repo"
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CreateBuilds < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table "build_reports", :force => true do |t|
|
4
|
+
t.column :sha, :string
|
5
|
+
t.column :branch, :string
|
6
|
+
t.column :build_time, :string
|
7
|
+
t.column :duration, :string
|
8
|
+
t.column :response, :string
|
9
|
+
t.column :status, :boolean
|
10
|
+
t.column :repo_id, :integer
|
11
|
+
end
|
12
|
+
#add_index :build_reports, :repo_id, :unique => true
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.down
|
16
|
+
drop_table "build_reports"
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
end
|
data/db/schema.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# This file is auto-generated from the current state of the database. Instead
|
3
|
+
# of editing this file, please use the migrations feature of Active Record to
|
4
|
+
# incrementally modify your database, and then regenerate this schema definition.
|
5
|
+
#
|
6
|
+
# Note that this schema.rb definition is the authoritative source for your
|
7
|
+
# database schema. If you need to create the application database on another
|
8
|
+
# system, you should be using db:schema:load, not running all the migrations
|
9
|
+
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
|
+
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
|
+
#
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define(version: 20150130143050) do
|
15
|
+
|
16
|
+
create_table "build_reports", force: true do |t|
|
17
|
+
t.string "sha"
|
18
|
+
t.string "branch"
|
19
|
+
t.string "build_time"
|
20
|
+
t.string "duration"
|
21
|
+
t.string "response"
|
22
|
+
t.boolean "status"
|
23
|
+
t.integer "repo_id"
|
24
|
+
end
|
25
|
+
|
26
|
+
create_table "repos", force: true do |t|
|
27
|
+
t.string "url"
|
28
|
+
t.string "name"
|
29
|
+
t.string "working_dir"
|
30
|
+
t.string "branch"
|
31
|
+
t.integer "gb_id"
|
32
|
+
t.text "github_data"
|
33
|
+
t.boolean "cached"
|
34
|
+
end
|
35
|
+
|
36
|
+
add_index "repos", ["gb_id"], name: "index_repos_on_gb_id", unique: true
|
37
|
+
|
38
|
+
end
|
data/examples/config.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
Perkins.application() do |app|
|
2
|
+
|
3
|
+
config do |c|
|
4
|
+
#redis_connection = Redis.new
|
5
|
+
#c.server = { host: "localhost", port:1234 }
|
6
|
+
c.redis = {host: "localhost"}
|
7
|
+
c.database = "./examples/database.yml"
|
8
|
+
c.github_client_id = ENV['GITHUB_CLIENT_ID']
|
9
|
+
c.github_client_secret = ENV['GITHUB_SECRET']
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
production:
|
2
|
+
adapter: sqlite3
|
3
|
+
database: db/production.sqlite3
|
4
|
+
pool: 5
|
5
|
+
timeout: 5000
|
6
|
+
|
7
|
+
development:
|
8
|
+
adapter: sqlite3
|
9
|
+
database: db/development.sqlite3
|
10
|
+
pool: 5
|
11
|
+
timeout: 5000
|
12
|
+
|
13
|
+
test:
|
14
|
+
adapter: sqlite3
|
15
|
+
database: db/test.sqlite3
|
16
|
+
pool: 5
|
17
|
+
timeout: 5000
|
data/examples/mongo.yml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
class Hash
|
2
|
+
# deep_merge_hash! by Stefan Rusterholz, see http://www.ruby-forum.com/topic/142809
|
3
|
+
DEEP_MERGER = proc do |key, v1, v2|
|
4
|
+
Hash === v1 && Hash === v2 ? v1.merge(v2, &DEEP_MERGER) : v2
|
5
|
+
end
|
6
|
+
|
7
|
+
def deep_merge(data)
|
8
|
+
merge(data, &DEEP_MERGER)
|
9
|
+
end unless Hash.method_defined?(:deep_merge)
|
10
|
+
|
11
|
+
def deep_merge!(data)
|
12
|
+
merge!(data, &DEEP_MERGER)
|
13
|
+
end unless Hash.method_defined?(:deep_merge!)
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Hash
|
2
|
+
def deep_symbolize_keys
|
3
|
+
inject({}) { |result, (key, value)|
|
4
|
+
result[(key.to_sym rescue key) || key] = case value
|
5
|
+
when Array
|
6
|
+
value.map { |value| value.is_a?(Hash) ? value.deep_symbolize_keys : value }
|
7
|
+
when Hash
|
8
|
+
value.deep_symbolize_keys
|
9
|
+
else
|
10
|
+
value
|
11
|
+
end
|
12
|
+
result
|
13
|
+
}
|
14
|
+
end unless Hash.method_defined?(:deep_symbolize_keys)
|
15
|
+
|
16
|
+
def deep_symbolize_keys!
|
17
|
+
replace(deep_symbolize_keys)
|
18
|
+
end unless Hash.method_defined?(:deep_symbolize_keys!)
|
19
|
+
end
|
20
|
+
|
Binary file
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Perkins
|
2
|
+
class Application
|
3
|
+
attr_accessor :host , :port, :working_dir, :redis, :database
|
4
|
+
attr_reader :server
|
5
|
+
attr_accessor :github_client_id, :github_client_secret
|
6
|
+
|
7
|
+
def initialize(opts={})
|
8
|
+
host = opts[:host] unless opts[:host].blank?
|
9
|
+
post = opts[:port] unless opts[:port].blank?
|
10
|
+
github_client_id = opts[:github_client_id] unless opts[:github_client_id].blank?
|
11
|
+
github_client_server = opts[:github_client_secret] unless opts[:github_client_secret].blank?
|
12
|
+
working_dir = opts[:working_dir] unless opts[:working_dir].blank?
|
13
|
+
end
|
14
|
+
|
15
|
+
def database=(file)
|
16
|
+
dbconfig = YAML::load(File.open(file))
|
17
|
+
@db = ActiveRecord::Base.establish_connection(dbconfig[ENV['RACK_ENV']])
|
18
|
+
end
|
19
|
+
|
20
|
+
def database
|
21
|
+
@db
|
22
|
+
end
|
23
|
+
|
24
|
+
def redis=(opts={})
|
25
|
+
namespace = opts.delete(:namespace) || :perkins
|
26
|
+
redis_connection = Redis.new(opts)
|
27
|
+
$redis = Redis::Namespace.new(namespace, :redis => redis_connection)
|
28
|
+
end
|
29
|
+
|
30
|
+
def as_json(options = {})
|
31
|
+
data = {}
|
32
|
+
fields = [:host, :port, :github_client_id,
|
33
|
+
:github_client_secret, :working_dir]
|
34
|
+
|
35
|
+
fields.each { |k| data[k] = send(k) }
|
36
|
+
data
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,4 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" height="152" width="154">
|
2
|
+
<path d="M0 640q0 209 103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5q0 -251 -146.5 -451.5t-378.5 -277.5q-27 -5 -39.5 7t-12.5 30v211q0 97 -52 142q57 6 102.5 18t94 39t81 66.5t53 105t20.5 150.5q0 121 -79 206q37 91 -8 204q-28 9 -81 -11t-92 -44 l-38 -24q-93 26 -192 26t-192 -26q-16 11 -42.5 27t-83.5 38.5t-86 13.5q-44 -113 -7 -204q-79 -85 -79 -206q0 -85 20.5 -150t52.5 -105t80.5 -67t94 -39t102.5 -18q-40 -36 -49 -103q-21 -10 -45 -15t-57 -5t-65.5 21.5t-55.5 62.5q-19 32 -48.5 52t-49.5 24l-20 3 q-21 0 -29 -4.5t-5 -11.5t9 -14t13 -12l7 -5q22 -10 43.5 -38t31.5 -51l10 -23q13 -38 44 -61.5t67 -30t69.5 -7t55.5 3.5l23 4q0 -38 0.5 -89t0.5 -54q0 -18 -13 -30t-40 -7q-232 77 -378.5 277.5t-146.5 451.5z" transform="scale(0.1, -0.1) translate(0, -1409)"/>
|
3
|
+
</svg>
|
4
|
+
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="8">
|
2
|
+
<g transform="translate(8, 4)">
|
3
|
+
<rect x="-8" y="-4" width="5" height="8">
|
4
|
+
<animateTransform id="a" attributeName="transform" type="scale" from="1,0.5" to="1" dur="0.4s" begin="0;b.end"/>
|
5
|
+
<animate attributeName="fill" from="#eee" to="#888" dur="0.4s" begin="0;b.end"/>
|
6
|
+
<animateTransform id="b" attributeName="transform" type="scale" from="1" to="1,0.5" dur="0.4s" begin="a.end"/>
|
7
|
+
<animate attributeName="fill" from="#888" to="#eee" dur="0.4s" begin="a.end"/>
|
8
|
+
</rect>
|
9
|
+
<rect x="-2" y="-4" width="4" height="8">
|
10
|
+
<animateTransform id="c" attributeName="transform" type="scale" from="1,0.5" to="1" dur="0.4s" begin="0.1s;d.end"/>
|
11
|
+
<animate attributeName="fill" from="#eee" to="#888" dur="0.4s" begin="0.1s;d.end"/>
|
12
|
+
<animateTransform id="d" begin="c.end" attributeName="transform" type="scale" to="1,0.5" from="1" dur="0.4s"/>
|
13
|
+
<animate attributeName="fill" from="#888" to="#eee" dur="0.4s" begin="c.end"/>
|
14
|
+
</rect>
|
15
|
+
<rect x="3" y="-4" width="5" height="8">
|
16
|
+
<animateTransform id="e" attributeName="transform" type="scale" from="1,0.5" to="1" dur="0.4s" begin="0.2s;f.end"/>
|
17
|
+
<animate attributeName="fill" from="#eee" to="#888" dur="0.4s" begin="0.2s;f.end"/>
|
18
|
+
<animateTransform id="f" attributeName="transform" type="scale" from="1" to="1,0.5" dur="0.4s" begin="e.end"/>
|
19
|
+
<animate attributeName="fill" from="#888" to="#eee" dur="0.4s" begin="e.end"/>
|
20
|
+
</rect>
|
21
|
+
</g>
|
22
|
+
</svg>
|
23
|
+
|
@@ -0,0 +1,95 @@
|
|
1
|
+
class window.LogView
|
2
|
+
|
3
|
+
constructor: (options={})->
|
4
|
+
@el = $(options.el)
|
5
|
+
@text = @el.text()
|
6
|
+
#console.log @text
|
7
|
+
@options = options
|
8
|
+
@reset()
|
9
|
+
|
10
|
+
render: ()->
|
11
|
+
parts = @split(@text)
|
12
|
+
|
13
|
+
#@log.set(ix, line)
|
14
|
+
@receive(part[0], part[1]) for part in parts
|
15
|
+
#console.log(@el)
|
16
|
+
#@log.set(0,"dfs")
|
17
|
+
|
18
|
+
receive: (ix, line) ->
|
19
|
+
@log.set(ix, line) #if @get('running')
|
20
|
+
|
21
|
+
split: (string) ->
|
22
|
+
string = string.replace(/\r\n/gm, "\n") # it seems split(/^/) would remove the newline, but not the \r here?
|
23
|
+
lines = string.split(/^/m)
|
24
|
+
parts = ([i, line] for line, i in lines)
|
25
|
+
console.log(JSON.stringify(parts))
|
26
|
+
parts = @slice(parts) if @options.slice
|
27
|
+
parts = @randomize(parts) if @options.randomize
|
28
|
+
# parts = @partition(parts) if @options.partition
|
29
|
+
parts
|
30
|
+
|
31
|
+
reset: ->
|
32
|
+
@clear()
|
33
|
+
@log = new Log
|
34
|
+
#log = new Log
|
35
|
+
#log.listeners.push(new Log) if @options.log
|
36
|
+
#log.listeners.push(new Log[@options.renderer])
|
37
|
+
#log.listeners.push(new Log.Folds) if @options.folds
|
38
|
+
#log.listeners.push(new Log.Instrumenter)
|
39
|
+
#log.listeners.push(new App.MetricsRenderer(@controller))
|
40
|
+
#@log = @options.buffer && new Log.Buffer(log) || log
|
41
|
+
|
42
|
+
slice: (array) ->
|
43
|
+
array.slice(0, @options.slice)
|
44
|
+
|
45
|
+
partition: (parts) ->
|
46
|
+
step = @rand(10)
|
47
|
+
|
48
|
+
# randomly split some of the parts into more parts
|
49
|
+
for _, i in Array::slice.apply(parts) by step
|
50
|
+
if @rand(10) > 7.5
|
51
|
+
split = @splitRand(parts[i][1], 5).map((chunk) -> [0, chunk])
|
52
|
+
parts.splice.apply(parts, [i, 1].concat(split))
|
53
|
+
|
54
|
+
# randomly join some of the parts into multi-line ones
|
55
|
+
for _, i in Array::slice.apply(parts) by step
|
56
|
+
if @rand(10) > 7.5
|
57
|
+
count = @rand(10)
|
58
|
+
joined = ''
|
59
|
+
joined += part[1] for part in parts.slice(i, count)
|
60
|
+
parts.splice(i, count, joined)
|
61
|
+
|
62
|
+
@renumber(parts)
|
63
|
+
|
64
|
+
renumber: (parts) ->
|
65
|
+
num = 0
|
66
|
+
parts[i][0] = num += 1 for _, i in parts
|
67
|
+
parts
|
68
|
+
|
69
|
+
randomize: (array, step) ->
|
70
|
+
@shuffle(array, i, step || 10) for _, i in array by step || 10
|
71
|
+
array
|
72
|
+
|
73
|
+
splitRand: (string, count) ->
|
74
|
+
size = (string.length / count) * 1.5
|
75
|
+
split = []
|
76
|
+
while string.length > 0
|
77
|
+
count = @rand(size) + 1
|
78
|
+
split.push(string.slice(0, count))
|
79
|
+
string = string.slice(count)
|
80
|
+
split
|
81
|
+
|
82
|
+
rand: (num) ->
|
83
|
+
Math.floor(Math.random() * num)
|
84
|
+
|
85
|
+
shuffle: (array, start, count) ->
|
86
|
+
for _, i in array.slice(start, start + count)
|
87
|
+
j = start + @rand(i + 1)
|
88
|
+
i = start + i
|
89
|
+
tmp = array[i]
|
90
|
+
array[i] = array[j]
|
91
|
+
array[j] = tmp
|
92
|
+
|
93
|
+
clear: ->
|
94
|
+
$('#log').empty()
|
95
|
+
#$('#events').empty()
|
@@ -0,0 +1,40 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
$(document).ready ()->
|
4
|
+
$("abbr.timeago").timeago()
|
5
|
+
|
6
|
+
|
7
|
+
#toggle item class to show respose
|
8
|
+
$(".build-item").on("click", ()->
|
9
|
+
#$(@).find(".build-response").toggleClass("hidden")
|
10
|
+
)
|
11
|
+
|
12
|
+
#reading
|
13
|
+
es = new EventSource("/stream")
|
14
|
+
es.onmessage = (e) ->
|
15
|
+
console.log("MESAGE RECEIVED")
|
16
|
+
console.log(e.data)
|
17
|
+
a = JSON.parse(e.data)
|
18
|
+
|
19
|
+
if a.repo.status == "stop"
|
20
|
+
$("#repo-#{a.repo.id} .fa-refresh").removeClass("fa-spin")
|
21
|
+
$(".repo-#{a.repo.id}-spinner.build-status").addClass("hidden")
|
22
|
+
if a.repo.status == "start"
|
23
|
+
debugger
|
24
|
+
$("#repo-#{a.repo.id} .fa-refresh").addClass("fa-spin")
|
25
|
+
$(".repo-#{a.repo.id}-spinner.build-status").removeClass("hidden")
|
26
|
+
|
27
|
+
return console.log "WFT?"
|
28
|
+
|
29
|
+
window.log_view = new LogView(el: "#log")
|
30
|
+
log_view.render()
|
31
|
+
#log_view.reset()
|
32
|
+
|
33
|
+
$ ->
|
34
|
+
$('#log').on 'mouseenter', 'a', ->
|
35
|
+
num = $(this.parentNode).prevAll('p').length + 1
|
36
|
+
url = window.location + ''
|
37
|
+
$(this).attr('href', url.replace(/#L\d+|(?=\?)|$/, '#L' + num))
|
38
|
+
|
39
|
+
$('#log').on 'click', '.fold', ->
|
40
|
+
$(this).toggleClass('open')
|