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