travis-surveillance 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,11 @@
1
+ env: NO_SIMPLECOV=true
2
+
3
+ language: ruby
4
+
5
+ rvm:
6
+ - 1.9.2
7
+ - 1.9.3
8
+ - jruby-19mode
9
+ - rbx-19mode
10
+
11
+ script: bundle exec rake test --trace
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in travis-monitor.gemspec
4
+ gemspec
5
+
6
+ gem "minitest", "~> 3.3"
data/Makefile ADDED
@@ -0,0 +1,19 @@
1
+ VERSION=$(shell ruby -r./lib/travis/surveillance/version -e "puts Travis::Surveillance::VERSION")
2
+
3
+ PROJECT?=$(notdir $(PWD))
4
+ GEM=$(PROJECT)-$(VERSION).gem
5
+
6
+ .PHONY: package
7
+ package: $(GEM)
8
+
9
+ .PHONY: $(GEM)
10
+ $(GEM):
11
+ gem build $(PROJECT).gemspec
12
+
13
+ .PHONY: install
14
+ install: $(GEM)
15
+ gem install $<
16
+
17
+ .PHONY: publish
18
+ publish: $(GEM)
19
+ gem push $(GEM)
data/README.md ADDED
@@ -0,0 +1,40 @@
1
+ ![](https://github.com/dylanegan/travis-surveillance/raw/master/travis-surveillance.jpg)
2
+
3
+ > I'll work anytime, anywhere.
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ $ gem install travis-surveillance
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ travis-surveillance --projects dylanegan/travis-surveillance
15
+ ```
16
+
17
+ ## License
18
+
19
+ Copyright (c) 2012 Dylan Egan
20
+
21
+ MIT License
22
+
23
+ Permission is hereby granted, free of charge, to any person obtaining
24
+ a copy of this software and associated documentation files (the
25
+ "Software"), to deal in the Software without restriction, including
26
+ without limitation the rights to use, copy, modify, merge, publish,
27
+ distribute, sublicense, and/or sell copies of the Software, and to
28
+ permit persons to whom the Software is furnished to do so, subject to
29
+ the following conditions:
30
+
31
+ The above copyright notice and this permission notice shall be
32
+ included in all copies or substantial portions of the Software.
33
+
34
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
35
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
36
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
37
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
38
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
39
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
40
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ require 'rake/testtask'
5
+
6
+ Rake::TestTask.new do |t|
7
+ t.libs.push "lib"
8
+ t.libs.push "spec"
9
+ t.test_files = FileList['spec/**/*_spec.rb']
10
+ t.verbose = true
11
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.expand_path("../../lib", __FILE__)
4
+
5
+ require "rubygems"
6
+ require "bundler/setup"
7
+
8
+ require "travis/surveillance/cli"
9
+
10
+ Travis::Surveillance::CLI.run
@@ -0,0 +1,68 @@
1
+ require "travis/surveillance/build"
2
+ require "travis/surveillance/job"
3
+ require "travis/surveillance/project"
4
+ require "travis/surveillance/surveyor"
5
+ require "travis/surveillance/version"
6
+
7
+ module Travis
8
+ module Surveillance
9
+ module Logger
10
+ def self.log(data, &block)
11
+ STDOUT.puts data
12
+ yield if block_given?
13
+ end
14
+ end
15
+
16
+ # Public: Allows the user to specify a logger for the log messages that Travis::Surveillance
17
+ # produces.
18
+ #
19
+ # logger = The object you want logs to be sent too
20
+ #
21
+ # Examples
22
+ #
23
+ # Travis::Surveillance.instrument_with(STDOUT.method(:puts))
24
+ # # => #<Method: IO#puts>
25
+ #
26
+ # Returns the logger object
27
+ def self.instrument_with(logger)
28
+ @logger = logger
29
+ end
30
+
31
+ # Internal: Top level log method for use by Travis::Surveillance
32
+ #
33
+ # data = Logging data (typically a hash)
34
+ # blk = block to execute
35
+ #
36
+ # Returns the response from calling the logger with the arguments
37
+ def self.log(data, &blk)
38
+ logger.call({ 'travis-surveillance' => true }.merge(data), &blk)
39
+ end
40
+
41
+ # Public: The logging location
42
+ #
43
+ # Returns an Object
44
+ def self.logger
45
+ @logger || Travis::Surveillance::Logger.method(:log)
46
+ end
47
+
48
+ # Public: Enable mocking mode
49
+ #
50
+ # Examples
51
+ #
52
+ # Travis::Surveillance.mock!
53
+ # # => true
54
+ def self.mock!
55
+ @mock = true
56
+ end
57
+
58
+ # Public: Check if mocking is enabled
59
+ #
60
+ # Examples
61
+ #
62
+ # Travis::Surveillance.mocking?
63
+ # # => false
64
+ def self.mocking?
65
+ @mock || false
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,112 @@
1
+ module Travis
2
+ module Surveillance
3
+ class Build
4
+ class Config
5
+ ATTRIBUTES = [:language]
6
+ attr_accessor *ATTRIBUTES
7
+
8
+ def initialize(attrs = {})
9
+ self.attributes = attrs
10
+ end
11
+
12
+ def attributes=(attrs = {})
13
+ attrs.each do |key, value|
14
+ send("#{key}=", value) if ATTRIBUTES.include?(key.to_sym)
15
+ end
16
+ end
17
+ end
18
+ ATTRIBUTES = [:author_name, :branch, :commit, :committed_at, :committer_name,
19
+ :compare_url, :duration, :finished_at, :id, :message, :number, :project,
20
+ :result, :started_at]
21
+ attr_accessor *ATTRIBUTES
22
+
23
+ alias_method :status, :result
24
+ alias_method :status=, :result=
25
+
26
+ def initialize(attrs = {})
27
+ self.attributes = attrs
28
+
29
+ populate unless @number
30
+ end
31
+
32
+ def add_job(json)
33
+ if job = job_for(json['id'])
34
+ return job
35
+ end
36
+
37
+ job = Job.new(json.merge({'build' => self}))
38
+ jobs << job
39
+ job
40
+ end
41
+
42
+ def attributes=(attrs = {})
43
+ attrs.each do |key, value|
44
+ next if value.nil?
45
+ if key == 'config'
46
+ config.attributes = value
47
+ else
48
+ send("#{key}=", (key[/_at$/] ? Time.parse(value) : value)) if ATTRIBUTES.include?(key.to_sym)
49
+ end
50
+ end
51
+ end
52
+
53
+ def building?
54
+ status.nil?
55
+ end
56
+
57
+ def config
58
+ @config ||= Config.new
59
+ end
60
+
61
+ def duration
62
+ if started_at && finished_at
63
+ finished_at - started_at
64
+ elsif started_at
65
+ Time.now - started_at
66
+ else
67
+ nil
68
+ end
69
+ end
70
+
71
+ def failed?
72
+ !status.nil? && !passed?
73
+ end
74
+
75
+ def job_for(id)
76
+ jobs.find { |j| j.id == id }
77
+ end
78
+
79
+ def jobs
80
+ @jobs ||= []
81
+ end
82
+
83
+ def passed?
84
+ !status.nil? && status.zero?
85
+ end
86
+
87
+ def state
88
+ if building?
89
+ 'building'
90
+ elsif passed?
91
+ 'passed'
92
+ else
93
+ 'failed'
94
+ end
95
+ end
96
+
97
+ private
98
+
99
+ def get_details
100
+ if Travis::Surveillance.mocking?
101
+ JSON.parse(IO.read(File.dirname(__FILE__) + "/../../../spec/support/builds/#{id}.json"))
102
+ else
103
+ JSON.parse(open("http://travis-ci.org/#{project.slug}/builds/#{id}.json").read)
104
+ end
105
+ end
106
+
107
+ def populate
108
+ self.attributes = get_details
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,83 @@
1
+ # encoding: utf-8
2
+
3
+ require "clamp"
4
+ require "scrolls"
5
+ require "terminal-table"
6
+ require "travis/surveillance"
7
+
8
+ module Travis
9
+ module Surveillance
10
+ module CLI
11
+ class Logger
12
+ def self.log(data, &block)
13
+ Scrolls.log(data, &block)
14
+ end
15
+ end
16
+
17
+ def self.run(*a)
18
+ MainCommand.run(*a)
19
+ end
20
+
21
+ class AbstractCommand < Clamp::Command
22
+ option ["-p", "--project"], "PROJECT", "projeter à regarder", :required => true
23
+
24
+ option ["--log"], :flag, "log the output to /tmp/travis-surveillance.log"
25
+
26
+ option "--version", :flag, "show version" do
27
+ puts "travis-surveillance #{Travis::Surveillance::VERSION}"
28
+ exit 0
29
+ end
30
+ end
31
+
32
+ class MainCommand < AbstractCommand
33
+ def execute
34
+ if log?
35
+ Scrolls::Log.stream = File.open('/tmp/travis-surveillance.log', 'w')
36
+ Travis::Surveillance.instrument_with(Travis::Surveillance::CLI::Logger.method(:log))
37
+ end
38
+
39
+ surveyor = Travis::Surveillance::Surveyor.new(Travis::Surveillance::Project.new(project))
40
+
41
+ project = surveyor.project
42
+ print "\x1b[2J\x1b[H"
43
+ print "Project: #{project.owner}/#{project.name}\n\n"
44
+ print "\x1b[H"
45
+ $stdout.flush
46
+
47
+ surveyor.survey do
48
+ print "\x1b[2J\x1b[H"
49
+ print "Project: #{project.owner}/#{project.name}\n\n"
50
+
51
+ if project.builds.any? && builds = project.builds.sort_by { |b| b.id }.reverse
52
+ latest = builds.first
53
+
54
+ table = Terminal::Table.new :title => "Latest Build: #{latest.number}", :headings => ['Job', 'State', 'Duration', 'ENV'] do |t|
55
+ latest.jobs.each do |job|
56
+ t << [job.number, job.state, job.duration, job.config.env]
57
+ end
58
+ end
59
+
60
+ print table
61
+
62
+ if builds.size > 1
63
+ print "\n\n"
64
+
65
+ table = Terminal::Table.new :title => "Build History", :headings => ['Build', 'State', 'Branch', 'Message', 'Duration'] do |t|
66
+ builds.each do |build|
67
+ next if build == latest
68
+ t << [build.number, build.state, build.branch, build.message, build.duration]
69
+ end
70
+ end
71
+
72
+ print table
73
+ end
74
+ end
75
+
76
+ print "\x1b[H"
77
+ $stdout.flush
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,93 @@
1
+ module Travis
2
+ module Surveillance
3
+ class Job
4
+ class Config
5
+ ATTRIBUTES = [:env, :rvm]
6
+ attr_accessor *ATTRIBUTES
7
+
8
+ def initialize(attrs = {})
9
+ self.attributes = attrs
10
+ end
11
+
12
+ def attributes=(attrs = {})
13
+ attrs.each do |key, value|
14
+ send("#{key}=", value) if ATTRIBUTES.include?(key.to_sym)
15
+ end
16
+ end
17
+ end
18
+
19
+ ATTRIBUTES = [:build, :finished_at, :id, :number, :result, :started_at]
20
+ attr_accessor *ATTRIBUTES
21
+
22
+ alias_method :status, :result
23
+ alias_method :status=, :result=
24
+
25
+ def initialize(attrs = {})
26
+ self.attributes = attrs
27
+
28
+ populate
29
+ end
30
+
31
+ def attributes=(attrs = {})
32
+ attrs.each do |key, value|
33
+ next if value.nil?
34
+ if key == 'config'
35
+ config.attributes = value
36
+ else
37
+ send("#{key}=", (key[/_at$/] ? Time.parse(value) : value)) if ATTRIBUTES.include?(key.to_sym)
38
+ end
39
+ end
40
+ end
41
+
42
+ def config
43
+ @config ||= Config.new
44
+ end
45
+
46
+ def duration
47
+ if started_at && finished_at
48
+ finished_at - started_at
49
+ elsif started_at
50
+ Time.now - started_at
51
+ else
52
+ nil
53
+ end
54
+ end
55
+
56
+ def failed?
57
+ !status.nil? && !passed?
58
+ end
59
+
60
+ def passed?
61
+ !status.nil? && status.zero?
62
+ end
63
+
64
+ def running?
65
+ status.nil?
66
+ end
67
+
68
+ def state
69
+ if running?
70
+ 'running'
71
+ elsif passed?
72
+ 'passed'
73
+ else
74
+ 'failed'
75
+ end
76
+ end
77
+
78
+ private
79
+
80
+ def get_details
81
+ if Travis::Surveillance.mocking?
82
+ JSON.parse(IO.read(File.dirname(__FILE__) + "/../../../spec/support/jobs/#{id}.json"))
83
+ else
84
+ JSON.parse(open("http://travis-ci.org/jobs/#{id}.json").read)
85
+ end
86
+ end
87
+
88
+ def populate
89
+ self.attributes = get_details
90
+ end
91
+ end
92
+ end
93
+ end