lariat 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 950b06d1da1b03616ddf4629ab66e2fa2210468e
4
+ data.tar.gz: 57de0b0f510fd0a84d10867ea879af7e6298281c
5
+ SHA512:
6
+ metadata.gz: cac215735848696f858cc43a27ce7d5a793bb30146d85c529779be8a45746bf79408972142e423073eb37f1d2b041a3b67a24bf3bcf70abd61878bd23796c497
7
+ data.tar.gz: f8f970ab52ed10809bcc19947367cf3105e45ea5fcf4f6ee11fc6ce8315be9ce7dfba74c3694a4d93154986c964df74c51d344e9e0ea53e85cab7f18bd8f2d28
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ gh_stats*
10
+ *.gem
11
+ Gemfile.lock
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ before_install: gem install bundler -v 1.11.2
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # lariat
2
+ Generate the Project Roundup issue
3
+
4
+ ## Purpose
5
+
6
+ This will generate the weekly Project Roundup issue. It currently performs the following activities:
7
+
8
+ - Searches for all issues with the #roundup tag
9
+ - Gathers statistics about
10
+ - PR Opened/Closed
11
+ - Priority [1|2|3] Issues Opened/Closed
12
+ - Pulls release statistics from Sabotage
13
+
14
+ Most of the queries are stored in `config/queries.yml`.
15
+
16
+ Once all the data is gathered, it will close the previous weeks Project Roundup issue and create a new one.
17
+
18
+ ## Usage
19
+
20
+ ```
21
+ $ git clone git@git.moneydesktop.com:dev/lariat.git
22
+ $ bundle
23
+ $ ./bin/lariat
24
+ ```
25
+
26
+ ### Feature Requests/Bug Fixes
27
+
28
+ ```
29
+ $ git clone git@git.moneydesktop.com:dev/lariat.git
30
+ $ cd lariat
31
+ $ git checkout -b your-branch-name
32
+ $ <your fixes go here>
33
+ $ git commit -a
34
+ ```
35
+
36
+ Open pull request. Bask in the admiration of your peers.
37
+
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "lariat"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
data/bin/lariat ADDED
@@ -0,0 +1,7 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift('.')
4
+
5
+ require 'lib/lariat'
6
+
7
+ Lariat::CLI.generate_project_roundup
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/lariat.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lariat/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lariat"
8
+ spec.version = Lariat::VERSION
9
+ spec.authors = ["MX Developers"]
10
+ spec.email = ["dev@mx.com"]
11
+ spec.homepage = "https://git.moneydesktop.com/dev/lariat"
12
+ spec.license = "MIT"
13
+
14
+ spec.summary = %q{Create project roundup}
15
+ spec.description = %q{Create project roundup.}
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|config)/}) }
18
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency "github_api", "~> 0.12"
23
+ spec.add_dependency "rest-client", "~> 2.0"
24
+ spec.add_dependency "safe_yaml", "~> 1.0"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.12"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec", "~> 3.0"
29
+ spec.add_development_dependency "pry", "~> 0.10"
30
+ spec.add_development_dependency "special_delivery", "~> 1.1"
31
+ end
data/lib/lariat/cli.rb ADDED
@@ -0,0 +1,62 @@
1
+ module Lariat
2
+ class CLI
3
+ def self.gather_project_roundup_data(build_stats)
4
+ queries = load_queries
5
+
6
+ gh = ::Lariat::Github.new("./config/github.yml")
7
+
8
+ args = { report_date: 1.week.ago.to_s.split(/ /).first }
9
+ issue_category_queries = queries["issue_category_queries"]
10
+
11
+ issue_summary_results = queries["issue_summary_queries"].map do |query|
12
+ results = gh.search_issues(query[:query] % args)
13
+ {:title => query[:title], total: results.total_count }
14
+ end
15
+
16
+ issue_category_results = issue_category_queries.keys.map do |key|
17
+ results = issue_category_queries[key].map do |query|
18
+ results = gh.search_issues(query[:query] % args)
19
+ results.total_count
20
+ end
21
+ { key => results }
22
+ end
23
+
24
+ pr_results = queries["pr_queries"].map do |query|
25
+ results = gh.search_issues(query[:query] % args)
26
+ {:section => query[:section], :title => query[:title], total: results.total_count }
27
+ end
28
+
29
+ top_issues_results = queries["top_issue_queries"].map do |query_definition|
30
+ results = gh.search_issues(query_definition[:query])
31
+ {:section => query_definition[:section], :title => query_definition[:title], :issues => results.to_h["items"] }
32
+ end
33
+
34
+ ::Lariat::IssueWriter.write_issue(build_stats, top_issues_results, issue_summary_results, issue_category_results, pr_results)
35
+ end
36
+
37
+ def self.generate_project_roundup(build_stats = nil)
38
+ build_stats ||= ::Lariat::SabotageStats.gather_stats("https://sabotage.internal.mx/stats.json", 7)
39
+
40
+ issue_body = gather_project_roundup_data(build_stats)
41
+ process_project_roundup(gh, queries["project_roundup_defaults"].first, issue_body)
42
+ end
43
+
44
+ def self.process_project_roundup(gh, issue_defaults, issue_body)
45
+ # find and close previous roundup
46
+ previous_issue = gh.search_issues('is:issue is:open user:%{user} repo:%{repository} label:"project roundup"' % issue_defaults.symbolize_keys)
47
+ unless previous_issue.total_count > 0
48
+ previous_issue = gh.search_issues('is:issue is:open "Project Roundup"')
49
+ end
50
+
51
+ gh.close_issue(previous_issue.items.first) if previous_issue.total_count > 0
52
+
53
+ # create new issue
54
+ date_params = { week_ending: Date.today.to_s }
55
+ gh.create_issue(issue_defaults['user'], issue_defaults['repository'], issue_defaults['title'] % date_params, issue_body, [issue_defaults['label']])
56
+ end
57
+
58
+ def self.load_queries
59
+ ::Lariat.load_config_from_yaml('./config/queries.yml')
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ module Lariat
2
+ class Github
3
+ module Issues
4
+ def close_issue(issue)
5
+ user,repo = get_user_from_repo_url(issue.repository_url)
6
+ issue_number = issue.number
7
+
8
+ handle.issues.edit(user, repo, issue_number, :state => 'closed')
9
+ end
10
+
11
+ def create_issue(user, repository, title, body, labels=[])
12
+ handle.issues.create(user, repository, :title => title, :body => body, :labels => labels)
13
+ end
14
+
15
+ def search_issues(query)
16
+ handle.search.issues(:q => query)
17
+ end
18
+
19
+ # https://git.moneydesktop.com/api/v3/repos/steve-newell/api-playground
20
+ def get_user_from_repo_url(url)
21
+ if url =~ /.*\/(.*)\/(.*)/
22
+ return $1,$2
23
+ else
24
+ return nil,nil
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,39 @@
1
+ require "github_api"
2
+ require "lariat/github/issues"
3
+
4
+ module Lariat
5
+ class Github
6
+
7
+ include ::Lariat::Github::Issues
8
+
9
+ def initialize(config_file)
10
+ @config = load_config(config_file)
11
+ initialize_git_client
12
+ @gh = ::Github.new
13
+ end
14
+
15
+ def handle
16
+ @gh
17
+ end
18
+
19
+ def initialize_git_client
20
+ unless @config['token']
21
+ puts "You must have a Github API Token. Create one, and add it to the local 'config/github.yml' and try again."
22
+ exit
23
+ end
24
+
25
+ ::Github.configure do |c|
26
+ c.oauth_token = @config['token']
27
+ c.site = @config['site']
28
+ c.endpoint = @config['endpoint']
29
+ end
30
+ end
31
+
32
+ def load_config(config_file)
33
+ ::Lariat.load_environment_config_from_yaml(config_file)
34
+ rescue
35
+ puts "You must have a Github API Token. Create one, and add it to the local 'config/github.yml' and try again."
36
+ exit
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,67 @@
1
+ module Lariat
2
+ class IssueWriter
3
+ ISSUE_HEADER = "Category | Opened | Closed | Outstanding \n-------------|------------|------------|-----------------\n"
4
+ PR_HEADER = "New | Closed | Still Open\n-------|-----------|--------------\n"
5
+
6
+ def self.write_issue(build_stats, top_issues_results, issue_summary_results, issue_category_results, pr_results)
7
+ StringIO.open do |stream|
8
+ write_issue_summary(stream, top_issues_results)
9
+ write_build_stats(stream, build_stats)
10
+ write_stats_summary(stream, issue_summary_results, issue_category_results, pr_results)
11
+ stream.string
12
+ end
13
+ end
14
+
15
+ def self.image_link(assignee)
16
+ return "" if assignee.blank?
17
+ "<img src='#{assignee[:avatar_url]}' width='16' title='#{assignee[:login]}'>"
18
+ end
19
+
20
+ def self.write_build_stats(stream, build_stats)
21
+ stream << "### Sabotage\n"
22
+ stream << "**#{build_stats[:releases_verified]}** Deploys\n"
23
+ stream << "**#{build_stats[:prs_closed]}** PRs closed\n"
24
+ end
25
+
26
+ def self.write_issue_summary(stream, top_issues_results)
27
+ top_issues_results.each do |results|
28
+ stream << "# #{results[:title]}\n"
29
+ if results[:issues].count == 0
30
+ stream << "**No Priority 1 Issues**\n"
31
+ next
32
+ end
33
+ results[:issues].each do |issue|
34
+ stream << "* [#{issue[:title]}](#{issue[:html_url]}) #{image_link(issue[:assignee])}\n"
35
+ end
36
+ stream << "\n"
37
+ end
38
+ end
39
+
40
+ def self.write_stats_summary(stream, issue_summary_results, issue_category_results, pr_results)
41
+ stream << "## Week in Review\n"
42
+ stream << "### Issues\n"
43
+
44
+ issue_summary_results.each do |issue|
45
+ stream << "**#{issue[:total]}** #{issue[:title]}\n"
46
+ end
47
+
48
+ stream << "#### Issue Breakdown\n"
49
+ stream << ISSUE_HEADER
50
+ issue_category_results.each do |summary|
51
+ values = summary.values.flatten
52
+ stream << "#{summary.keys.first} | #{values[0]} | #{values[1]} | #{values[2]}\n"
53
+ end
54
+
55
+ write_pr_summary(stream, pr_results)
56
+ end
57
+
58
+ def self.write_pr_summary(stream, pr_results)
59
+ stream << "\n"
60
+ stream << "### Pull Requests\n"
61
+ stream << PR_HEADER
62
+ pr_results.each do |pr|
63
+ stream << "#{pr[:total]} | "
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,23 @@
1
+ require 'rest-client'
2
+ require 'json'
3
+
4
+ module Lariat
5
+ class SabotageStats
6
+ def self.gather_stats(url, date_offset)
7
+ response = RestClient.get(url)
8
+
9
+ stats = JSON.parse(response)
10
+
11
+ verified = 0
12
+ closed = 0
13
+
14
+ date_offset.times do |i|
15
+ key = (Date.today - i).to_s
16
+ verified += stats[key]["releases_verified"]
17
+ closed += stats[key]["prs_closed"]
18
+ end
19
+
20
+ return { :releases_verified => verified, :prs_closed => closed }
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module Lariat
2
+ VERSION = "0.1.1"
3
+ end
data/lib/lariat.rb ADDED
@@ -0,0 +1,31 @@
1
+ require "safe_yaml"
2
+
3
+ require "lariat/cli"
4
+ require "lariat/github"
5
+ require "lariat/issue_writer"
6
+ require "lariat/sabotage_stats"
7
+ require "lariat/version"
8
+
9
+ module Lariat
10
+ def self.load_config_from_yaml(relative_config_path)
11
+ full_config_path = ::File.expand_path(relative_config_path)
12
+ yaml_string = ::ERB.new(::File.read(full_config_path)).result
13
+ config = ::YAML.load(yaml_string, :safe => true)
14
+ config.respond_to?(:with_indifferent_access) ? config.with_indifferent_access : config
15
+ end
16
+
17
+ def self.load_environment_config_from_yaml(relative_config_path, environment = nil)
18
+ environment ||= ::Lariat.get_environment
19
+
20
+ config = load_config_from_yaml(relative_config_path)
21
+ environment_config = config[environment]
22
+
23
+ fail "#{environment} environment not found in #{relative_config_path}." unless environment_config
24
+ environment_config
25
+ end
26
+
27
+ def self.get_environment
28
+ return "development" unless defined?(::Rails)
29
+ ::Rails.env
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lariat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - MX Developers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-08-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: github_api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.12'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rest-client
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: safe_yaml
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.10'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.10'
111
+ - !ruby/object:Gem::Dependency
112
+ name: special_delivery
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.1'
125
+ description: Create project roundup.
126
+ email:
127
+ - dev@mx.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
135
+ - Gemfile
136
+ - README.md
137
+ - Rakefile
138
+ - bin/console
139
+ - bin/lariat
140
+ - bin/setup
141
+ - lariat.gemspec
142
+ - lib/lariat.rb
143
+ - lib/lariat/cli.rb
144
+ - lib/lariat/github.rb
145
+ - lib/lariat/github/issues.rb
146
+ - lib/lariat/issue_writer.rb
147
+ - lib/lariat/sabotage_stats.rb
148
+ - lib/lariat/version.rb
149
+ homepage: https://git.moneydesktop.com/dev/lariat
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.4.8
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: Create project roundup
173
+ test_files: []