jira_report 0.0.2 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 426236177e3ecba31533d4d70783a02fd3c1a39e
4
- data.tar.gz: ce26fba802985e9781a037643e0effcc6e7d5742
3
+ metadata.gz: 3a9197875b688ab8f04bca3835f25bc7edb62ac7
4
+ data.tar.gz: c048244ac02abeaad3fa7ff017d24bbef0869e4a
5
5
  SHA512:
6
- metadata.gz: 9e1dd5d086623cb5d271349b13a309eb10f7102f4c68b3dcd02af887d8b83ba7163d1a6ebe58d230e25e9e5ace310e5e3ef696e30f634476cf3c401c3fd7a903
7
- data.tar.gz: 4b5fe161b7e8af39ad69008f5ecbd0ed4bcc9c076c95c22cf9f127e5a245141fb623c98904992415f5955d799e5be5429723018d5a6f58acca48072d002266f2
6
+ metadata.gz: aa32b19bbf05ec4c43208314a4bc73b4beef7bf2edfaa8df2249f054aa089b4d4f4eac9659c3d2e507cb5423fcb5604e0489bb46afb82cae6cd715dfc54c0349
7
+ data.tar.gz: 192b673da211b18c7725ab369e0434b03533ddb5038a7890c2cd211da1d06664e289c19a2cd7eed69b678f8d9ea00c93e1e69451c61100f0c8a61f0ce79d26c6
data/README.md CHANGED
@@ -1,27 +1,23 @@
1
- [![Gem Version](https://badge.fury.io/rb/jira_report.svg)](https://rubygems.org/gems/jira_report)
2
- [![Build Status](https://api.travis-ci.org/veelenga/jira_report.svg)](https://travis-ci.org/veelenga/jira_report)
3
-
4
- Jira Report
1
+ Jira Report [![Gem Version](https://badge.fury.io/rb/jira_report.svg)](https://rubygems.org/gems/jira_report) [![Build Status](https://api.travis-ci.org/veelenga/jira_report.svg)](https://travis-ci.org/veelenga/jira_report)
5
2
  ===========================
6
3
 
7
- Queries user activities for specified period of time and prints it to console.
4
+ Queries user activities from jira for specified period of time and prints it to console.
8
5
 
9
6
  ##Installation
10
7
  ```
11
- $gem install jira_report
8
+ $ gem install jira_report
12
9
  ```
13
10
 
14
11
  ##Usage
15
- ```sh
16
- $jira-report -h
17
- Usage: jira-report [options]
18
- -u, --username username Username to query activity report.
19
- -c, --config config Path to config file. USER_HOME/.jira-report is default.
20
- ```
21
12
 
13
+ Just run it. `jira-report` will ask you your jira location, who you are and what's your password:
22
14
  ```
23
- $jira-report -u admin
15
+ $ jira-report
16
+ Jira url: jira.company.com
17
+ Jira username: admin
18
+ Jira password:
24
19
  Querying jira...
20
+
25
21
  Jira activity report for [admin]:
26
22
 
27
23
  Created: 2
@@ -41,19 +37,55 @@ Resolved: 8
41
37
  Reopened: 0
42
38
 
43
39
  Closed: 5
44
- TST-6943 - Remove redundant org.apache.log4j dependcy from common part
40
+ TST-6943 - Remove redundant org.apache.log4j dependency from common part
45
41
  TST-5862 - Unable to install NGinx on HP-UX with Java 6
46
42
  TST-5857 - Put back support for Jdk 1.6
47
43
  TST-5840 - NGinx fails to handle interaction initiated
48
44
  GSM-364 - Migration of existing units
49
45
  ```
50
46
 
47
+ `url`, `username`, `password` and some other parameters can be added to [configuration file](#configuration). Also you can use mixed approach (keep some options in file, others enter from command line). For example if you do not want to keep password in configuration file, just don't, you will be asked.
48
+
49
+ Also you can use it directly in ruby:
50
+ ```ruby
51
+ require 'jira_report'
52
+
53
+ def print_issues(issues)
54
+ issues.each do |issue|
55
+ puts " #{issue['key']} - #{issue['fields']['summary']}"
56
+ end
57
+ end
58
+
59
+ reporter = JiraReport::Reporter.new('jira.company.com', 'admin', 's3cr3t')
60
+ # returns all created issues by 'my_jira_name'
61
+ all_created = reporter.created('my_jira_name')
62
+
63
+ # returns closed issues by 'admin' last week
64
+ weekly_closed = reporter.closed('admin', '-1w')
65
+
66
+ # returns reopened issues by 'usr' in period starting
67
+ # from two weeks ago and ending one week ago.
68
+ reopened = reporter.reopened('usr', '-2w', '-1w')
69
+
70
+ print_issues(weekly_closed)
71
+ ```
72
+
51
73
  ##Configuration
52
- Default path to configuration file is `~/.jira-report`. All settings are optional and may be read from user input. See [sample](example/jira-report.sample).
74
+ Path to configuration file can be specified by `-c` command line argument. `~/.jira-report` is default.
53
75
 
54
- Period is set by two options `period_from` and `period_till`. Both options support [advanced jira searching](https://confluence.atlassian.com/display/JIRA/Advanced+Searching) and accept dates, jira functions, aliasing. For example:
76
+ There are three main options in config file to query jira:
77
+ ```
78
+ url=jira.company.com
79
+ username=username
80
+ password=s3cr3t
81
+ ```
82
+ all those are optional and if not specified user will be asked to enter it from command line.
55
83
 
84
+ Period is set by two options `period_from` and `period_till`. Both options support [advanced jira searching](https://confluence.atlassian.com/display/JIRA/Advanced+Searching) and accept dates, jira functions, aliasing. For example:
56
85
  ```
57
- period_from=-3w
86
+ period_from=-1w
58
87
  period_till=now()
59
88
  ```
89
+ If those options not specified in configuration file, last week activities will be queried (just as in example above).
90
+
91
+ You can look at configuration file [sample](example/jira-report.sample) in repository.
data/bin/jira-report CHANGED
@@ -1,7 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require 'jira_report'
3
+ require 'jira_report/cli'
4
4
 
5
- parameters = JiraReport::Cli.new
6
- settings = JiraReport::Settings.new(parameters.ini)
7
- JiraReport::JiraReport.new(settings, parameters.username).report
5
+ JiraReport::Cli.new.run
data/jira_report.gemspec CHANGED
@@ -18,7 +18,9 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ['lib']
20
20
 
21
- spec.add_runtime_dependency 'inifile', '~> 3.0'
21
+ spec.required_ruby_version = '>= 1.9.3'
22
+
23
+ spec.add_runtime_dependency 'parseconfig', '~> 1.0'
22
24
  spec.add_runtime_dependency 'rest-client', '~> 1.7'
23
25
  spec.add_development_dependency 'bundler', '~> 1.7'
24
26
  spec.add_development_dependency 'rake', '~> 10.0'
data/lib/jira_report.rb CHANGED
@@ -1,97 +1 @@
1
- require 'rest_client'
2
- require 'json'
3
- require 'uri'
4
-
5
- require 'jira_report/settings'
6
- require 'jira_report/cli'
7
-
8
- module JiraReport
9
- # Base class that generate jira activity report
10
- class JiraReport
11
- attr_accessor :from, :till, :username
12
-
13
- def initialize(init_set, username)
14
- @username = username ? username : init_set.username
15
- @search_url = jira_search_url(init_set.url,
16
- init_set.username,
17
- init_set.password)
18
-
19
- @from = init_set.period_from
20
- @till = init_set.period_till
21
- end
22
-
23
- def report
24
- puts "\nQuerying jira..."
25
-
26
- begin
27
- created = query(jql_created)
28
- resolved = query(jql_resolved)
29
- reopened = query(jql_reopened)
30
- closed = query(jql_closed)
31
-
32
- puts "\nJira activity report for [#{@username}]:"
33
-
34
- puts "\nCreated: #{created.length}"
35
- print_issues(created)
36
-
37
- puts "\nResolved: #{resolved.length}"
38
- print_issues(resolved)
39
-
40
- puts "\nReopened: #{reopened.length}"
41
- print_issues(reopened)
42
-
43
- puts "\nClosed: #{closed.length}"
44
- print_issues(closed)
45
-
46
- rescue SocketError => e
47
- puts "Unable to connect to jira: '#{e.message}'"
48
- rescue Exception => e
49
- puts "Unable to prepare activity report: '#{e.message}'"
50
- end
51
- end
52
-
53
- private
54
-
55
- def jira_search_url(url, username, password)
56
- "http://#{username}:#{password}@#{url}/rest/api/2/search?"
57
- end
58
-
59
- def jql_created
60
- "jql=created>=#{@from} " \
61
- "AND created<=#{@till} "\
62
- "AND reporter=#{@username}"
63
- end
64
-
65
- def jql_resolved
66
- "jql=resolved>=#{@from} " \
67
- "AND resolved<=#{@till} "\
68
- "AND 'First Resolution User'=#{@username}"
69
- end
70
-
71
- def jql_closed
72
- "jql='First Closed Date'>=#{@from} " \
73
- "AND 'First Closed Date'<=#{@till} "\
74
- "AND 'First Closed User'=#{@username}"
75
- end
76
-
77
- def jql_reopened
78
- "jql='First Reopened Date'>=#{@from} " \
79
- "AND 'First Reopened Date'<=#{@till} "\
80
- "AND 'First Reopened User'=#{@username}"
81
- end
82
-
83
- def query(jql)
84
- response = RestClient.get(@search_url + URI.escape(jql))
85
- unless response.code == 200
86
- fail "Got wrong response code: #{response.code}"
87
- end
88
- JSON.parse(response.body)['issues']
89
- end
90
-
91
- def print_issues(issues)
92
- issues.each do |issue|
93
- puts " #{issue['key']} - #{issue['fields']['summary']}"
94
- end
95
- end
96
- end
97
- end
1
+ require 'jira_report/reporter'
@@ -1,31 +1,130 @@
1
- require 'optparse'
1
+ require 'jira_report/options'
2
+ require 'jira_report/config_loader'
3
+ require 'jira_report/reporter'
2
4
 
3
5
  module JiraReport
4
- # Prepares command line parameters using OptionParser
5
6
  class Cli
6
- attr_reader :username, :ini
7
+ DEFAULT_CONFIG_PATH = '~/.jira-report'
7
8
 
8
9
  def initialize
9
- options = parse
10
- @username = options[:username]
11
- @ini = options[:ini] ? options[:ini] : "~/.jira-report"
10
+ @config = {}
11
+ end
12
+
13
+ def run(args=ARGV)
14
+ begin
15
+ options = Options.new(args).options
16
+ act_on_option(options)
17
+
18
+ load_config(options[:config])
19
+ ask_missing_options
20
+ add_usr(options[:username])
21
+
22
+ report
23
+ rescue => e
24
+ puts "error: '#{e.message}'"
25
+ exit 1
26
+ rescue SystemExit => e
27
+ exit e.status
28
+ rescue Interrupt => e
29
+ puts 'Interrupted'
30
+ exit 130
31
+ rescue Exception => e
32
+ puts "fatal: '#{e.message}'"
33
+ exit 255
34
+ end
12
35
  end
13
36
 
14
37
  private
15
38
 
16
- def parse
17
- options = {}
18
- OptionParser.new do |opts|
19
- opts.banner = 'Usage: jira-report [options]'
20
- opts.on('-u', '--username username', 'Username to query activity report.') do |u|
21
- options[:username] = u
22
- end
23
- opts.on('-c', '--config config', 'Path to config file. ' \
24
- 'USER_HOME/.jira-report is default.') do |s|
25
- options[:ini] = s
26
- end
27
- end.parse!
28
- options
39
+ def report
40
+ reporter = Reporter.new(
41
+ @config[:url], @config[:username], @config[:password]
42
+ )
43
+
44
+ puts "\nQuerying jira..."
45
+
46
+ created = reporter.created(
47
+ @config[:usr], @config[:period_from], @config[:period_till]
48
+ )
49
+ resolved = reporter.resolved(
50
+ @config[:usr], @config[:period_from], @config[:period_till]
51
+ )
52
+ reopened = reporter.reopened(
53
+ @config[:usr], @config[:period_from], @config[:period_till]
54
+ )
55
+ closed = reporter.closed(
56
+ @config[:usr], @config[:period_from], @config[:period_till]
57
+ )
58
+
59
+ puts "\nJira activity report for [#{@config[:usr]}]:"
60
+
61
+ puts "\nCreated: #{created.length}"
62
+ print_issues(created)
63
+
64
+ puts "\nResolved: #{resolved.length}"
65
+ print_issues(resolved)
66
+
67
+ puts "\nReopened: #{reopened.length}"
68
+ print_issues(reopened)
69
+
70
+ puts "\nClosed: #{closed.length}"
71
+ print_issues(closed)
72
+ end
73
+
74
+ def print_issues(issues)
75
+ issues.each do |issue|
76
+ puts " #{issue['key']} - #{issue['fields']['summary']}"
77
+ end
78
+ end
79
+
80
+ # Does required actions on specified option if needed.
81
+ def act_on_option(options)
82
+ if options.include? :version
83
+ puts VERSION
84
+ exit(0)
85
+ end
86
+ # ...
87
+ end
88
+
89
+ # Loads configuration from configuration file.
90
+ def load_config(path)
91
+ config_path = path ? path : DEFAULT_CONFIG_PATH
92
+ @config = ConfigLoader.load_config(config_path)
93
+ end
94
+
95
+ # Reads required options from user input if those
96
+ # were missed.
97
+ def ask_missing_options
98
+ @config[:url] = ask('Jira url: ') unless @config[:url]
99
+ @config[:username] = ask('Jira username: ') unless @config[:username]
100
+ @config[:password] = ask('Jira password: '){
101
+ STDIN.noecho(&:gets).chomp!
102
+ } unless @config[:password]
103
+ if !@config[:period_from] && !@config[:period_till]
104
+ @config[:period_from] = '-1w'
105
+ @config[:period_till] = 'now()'
106
+ end
107
+ end
108
+
109
+ # Asks user to enter something
110
+ def ask(message, &block)
111
+ print message
112
+ if block_given?
113
+ yield block
114
+ else
115
+ gets.chomp!
116
+ end
117
+ end
118
+
119
+ # Adds to config username to query about.
120
+ def add_usr(usr)
121
+ if usr
122
+ @config[:usr] = usr
123
+ else
124
+ # use username for authentication if username
125
+ # to query not specified.
126
+ @config[:usr] = @config[:username]
127
+ end
29
128
  end
30
129
  end
31
130
  end
@@ -0,0 +1,21 @@
1
+ require 'parseconfig'
2
+
3
+ module JiraReport
4
+ # Loads configuration from configuration file.
5
+ class ConfigLoader
6
+ def self.load_config(path)
7
+ begin
8
+ config = ParseConfig.new(File.expand_path(path))
9
+ symboled_hash(config.params)
10
+ rescue Exception => e
11
+ raise RuntimeError.new "Error loading config: #{e}"
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def self.symboled_hash(h)
18
+ h.inject({}){ |m, (k,v)| m[k.to_sym] = v; m }
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,78 @@
1
+ require 'optparse'
2
+
3
+ module JiraReport
4
+
5
+ # Collection of input argument descriptions.
6
+ class OptionsText
7
+ TEXT = {
8
+ username: 'Specify jira username to query statistic about.',
9
+ config: 'Specify path to configuration file.',
10
+ version: 'Display version.'
11
+ }
12
+ end
13
+
14
+ # Parses and validates array of input arguments.
15
+ class Options
16
+ # Accepts arguments to be parsed.
17
+ # Raises ArgumentError if args is not kind of Array.
18
+ def initialize(args)
19
+ unless args.kind_of? Array
20
+ raise ArgumentError.new "Array expected, but was #{args.class}"
21
+ end
22
+ @options = {}
23
+ parse(args)
24
+ end
25
+
26
+ # Returns clone of option hash
27
+ def options
28
+ @options.dup
29
+ end
30
+
31
+ # Returns option from option list with name that converted
32
+ # to symbol.
33
+ def get(sym)
34
+ @options[sym]
35
+ end
36
+
37
+ # Returns true if option list includes option which name
38
+ # converted to symbol.
39
+ def include?(sym)
40
+ @options.include? sym
41
+ end
42
+
43
+ private
44
+
45
+ # Parses args. Adds parsed argument to option hash
46
+ # in next format:
47
+ # :option_name => option
48
+ # Where :option_name - corresponding symbol of
49
+ # option name.
50
+ def parse(args)
51
+ OptionParser.new do |opts|
52
+ opts.banner = 'Usage: jira-report [options]'
53
+
54
+ option(opts, '-u', '--username USERNAME')
55
+ option(opts, '-c', '--config FILE')
56
+ option(opts, '-v', '--version')
57
+ end.parse!(args)
58
+ end
59
+
60
+ # Adds new option.
61
+ def option(opts, *args)
62
+ opt_sym = long_opt_sym(*args)
63
+ args << OptionsText::TEXT[opt_sym]
64
+ opts.on(*args) { |arg| @options[opt_sym] = arg }
65
+ end
66
+
67
+ # Looks through arg list to find long option
68
+ # and converts it to sym. Assumes that long
69
+ # option always present.
70
+ #
71
+ # For example:
72
+ # ['-c', '--config-file FILE'] => :config_file
73
+ def long_opt_sym(*args)
74
+ long_opt = args.find{ |arg| arg.start_with? '--' }
75
+ long_opt[2..-1].sub(/ .*/, '').gsub('-', '_').to_sym
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,134 @@
1
+ require 'rest_client'
2
+ require 'json'
3
+ require 'uri'
4
+
5
+ module JiraReport
6
+ # With this class you can easily query user activities from jira
7
+ # in specified period of time.
8
+ #
9
+ # ==== Examples
10
+ #
11
+ # reporter = Reporter.new('jira.company.url', 'admin', 's3cr3t')
12
+ #
13
+ # # returns all created issues by 'my_jira_name'
14
+ # all_created = reporter.created('my_jira_name')
15
+ #
16
+ # # returns closed issues by 'admin' last week
17
+ # weekly_closed = reporter.closed('admin', '-1w')
18
+ #
19
+ # # returns reopened issues by 'usr' in period starting
20
+ # # from two weeks ago and ending one week ago.
21
+ # reopened = reporter.reopened('usr', '-2w', '-1w')
22
+ class Reporter
23
+ # Initializes reporter.
24
+ #
25
+ # ==== Attributes
26
+ #
27
+ # * +url+ - jira URL in `jira.company.com` format.
28
+ # * +usr+ - jira username.
29
+ # * +pass+ - jira password.
30
+ def initialize(url, usr, pass)
31
+ @search_url = jira_api_url(url, usr, pass);
32
+ end
33
+
34
+ # Queries created issues by usr in specified period.
35
+ #
36
+ # ==== Attributes
37
+ #
38
+ # * +usr+ - username query statistic about.
39
+ # * +from+ - period of time starts with this value (jql format).
40
+ # * +till+ - period of time ends with this value (jql format).
41
+ def created(usr, from=nil, till=nil)
42
+ query_issues(jql_created usr, from, till)
43
+ end
44
+
45
+ # Queries resolved issues by usr in specified period.
46
+ #
47
+ # ==== Attributes
48
+ #
49
+ # * +usr+ - username query statistic about.
50
+ # * +from+ - period of time starts with this value (jql format).
51
+ # * +till+ - period of time ends with this value (jql format).
52
+ def resolved(usr, from=nil, till=nil)
53
+ query_issues(jql_resolved usr, from, till)
54
+ end
55
+
56
+ # Queries reopened issues by usr in specified period.
57
+ #
58
+ # ==== Attributes
59
+ #
60
+ # * +usr+ - username query statistic about.
61
+ # * +from+ - period of time starts with this value (jql format).
62
+ # * +till+ - period of time ends with this value (jql format).
63
+ def reopened(usr, from=nil, till=nil)
64
+ query_issues(jql_reopened usr, from, till)
65
+ end
66
+
67
+ # Queries closed issues by usr in specified period.
68
+ #
69
+ # ==== Attributes
70
+ #
71
+ # * +usr+ - username query statistic about.
72
+ # * +from+ - period of time starts with this value (jql format).
73
+ # * +till+ - period of time ends with this value (jql format).
74
+ def closed(usr, from=nil, till=nil)
75
+ query_issues(jql_closed usr, from, till)
76
+ end
77
+
78
+ # Queries issues using jql query.
79
+ #
80
+ # ==== Attributes
81
+ #
82
+ # * +jql+ - query in jira query languages.
83
+ def query_issues(jql)
84
+ response = RestClient.get(@search_url + URI.escape(jql))
85
+ unless response.code == 200
86
+ fail "Response code: #{response.code}"
87
+ end
88
+ JSON.parse(response.body)['issues']
89
+ end
90
+
91
+ private
92
+
93
+ # Returns jira rest api search url.
94
+ def jira_api_url(url, username, password)
95
+ "http://#{username}:#{password}@#{url}/rest/api/2/search?"
96
+ end
97
+
98
+ # Prepares jql query based on parameters to
99
+ # search created issues.
100
+ def jql_created(usr, from, till)
101
+ jql = 'jql='
102
+ jql << "created>=#{from} AND " if from
103
+ jql << "created<=#{till} AND " if till
104
+ jql << "reporter=#{usr}"
105
+ end
106
+
107
+ # Prepares jql query based on parameters to
108
+ # search resolved issues.
109
+ def jql_resolved(usr, from, till)
110
+ jql = 'jql='
111
+ jql << "resolved>=#{from} AND " if from
112
+ jql << "resolved<=#{till} AND " if till
113
+ jql << "'First Resolution User'=#{usr}"
114
+ end
115
+
116
+ # Prepares jql query based on parameters to
117
+ # search reopened issues.
118
+ def jql_reopened(usr, from, till)
119
+ jql = 'jql='
120
+ jql << "'First Reopened Date'>=#{from} AND " if from
121
+ jql << "'First Reopened Date'<=#{till} AND " if till
122
+ jql << "'First Reopened User'=#{usr}"
123
+ end
124
+
125
+ # Prepares jql query based on parameters to
126
+ # search closed issues.
127
+ def jql_closed(usr, from, till)
128
+ jql = 'jql='
129
+ jql << "'First Closed Date'>=#{from} AND " if from
130
+ jql << "'First Closed Date'<=#{till} AND " if till
131
+ jql << "'First Closed User'=#{usr}"
132
+ end
133
+ end
134
+ end
@@ -1,3 +1,3 @@
1
1
  module JiraReport
2
- VERSION = "0.0.2"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,43 @@
1
+ require 'spec_helper'
2
+ require 'jira_report/config_loader'
3
+
4
+ module JiraReport
5
+ describe ConfigLoader do
6
+ it 'raises error if wrong path to configuration file' do
7
+ expect{ ConfigLoader.load_config('wrong/path') }.to raise_error RuntimeError
8
+ end
9
+
10
+ context 'when file exists' do
11
+ let(:filename){ 'test.conf' }
12
+ let(:option){ 'username' }
13
+ let(:value){ 'JohnDoe' }
14
+
15
+ before do
16
+ FileUtils.touch(filename)
17
+ end
18
+
19
+ def add_content(filename, content)
20
+ f = File.new(filename, 'a+')
21
+ f.write(content)
22
+ f.flush
23
+ f.close
24
+ end
25
+
26
+ after do
27
+ FileUtils.rm_r(filename)
28
+ end
29
+
30
+ it 'reads empty file correctly' do
31
+ config = ConfigLoader.load_config(filename)
32
+ expect(config).not_to be nil
33
+ expect(config).to be_empty
34
+ end
35
+
36
+ it 'read file with options' do
37
+ add_content(filename, "#{option}=#{value}")
38
+ config = ConfigLoader.load_config(filename)
39
+ expect(config).to include(option.to_sym => value)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+ require 'jira_report/options'
3
+
4
+ module JiraReport
5
+ describe Options do
6
+ def check_field(opts, s, v)
7
+ o = Options.new(opts)
8
+ expect(o.get(s)).to eq(v)
9
+ expect(o.options.include?(s)).to be true
10
+ expect(o.include?(s)).to be true
11
+ end
12
+
13
+ def check_flag(opts, s)
14
+ o = Options.new(opts)
15
+ expect(o.include?(s)).to be true
16
+ end
17
+
18
+ def check_field_err(opts, err=Exception)
19
+ expect{ Options.new(opts) }.to raise_error err
20
+ end
21
+
22
+ context 'when non-option passed' do
23
+ it 'should throw error if wrong option' do
24
+ check_field_err(['-1', 'value'], OptionParser::InvalidOption)
25
+ end
26
+ it 'should throw error if nil passed' do
27
+ check_field_err(nil, ArgumentError)
28
+ end
29
+ end
30
+
31
+ context 'when no arguments passed' do
32
+ let(:opt) { Options.new([]) }
33
+
34
+ it 'should have no options' do
35
+ expect(opt.options.empty?).to be true
36
+ end
37
+ end
38
+
39
+ describe '-h' do
40
+ before(:each) do
41
+ $stdout = StringIO.new
42
+ $stderr = StringIO.new
43
+ end
44
+ after(:each) do
45
+ $stdout = STDOUT
46
+ $stderr = STDERR
47
+ end
48
+
49
+ it 'exits clearly' do
50
+ expect{ Options.new(['-h']) }.to raise_error SystemExit
51
+ expect{ Options.new(['--help']) }.to raise_error SystemExit
52
+ end
53
+ end
54
+
55
+ describe '-v' do
56
+ it 'is accepted' do
57
+ check_flag(['-v'], :version)
58
+ check_flag(['--version'], :version)
59
+ end
60
+ end
61
+
62
+ describe '-u' do
63
+ it 'is accepted' do
64
+ usr = 'JohnDoe'
65
+ check_field(['-u', usr], :username, usr)
66
+ check_field(['--username', usr], :username, usr)
67
+ end
68
+ it 'is expected an error when argument not given' do
69
+ check_field_err(['-u'], OptionParser::MissingArgument)
70
+ check_field_err(['--username'], OptionParser::MissingArgument)
71
+ end
72
+ end
73
+
74
+ describe '-c' do
75
+ it 'is accepted' do
76
+ file = './test'
77
+ check_field(['-c', file], :config, file)
78
+ check_field(['--config', file], :config, file)
79
+ end
80
+ it 'is expected an error when argument not given' do
81
+ check_field_err(['-c'])
82
+ check_field_err(['--config'])
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,181 @@
1
+ require 'spec_helper'
2
+
3
+ module JiraReport
4
+ describe JiraReport do
5
+ let(:jrep) { Reporter.new('url', 'admin', '*****') }
6
+
7
+ describe '#query_issues' do
8
+ it 'should throw exception' do
9
+ begin
10
+ jrep.query_issues('my_jql')
11
+ fail Exception, 'exception expected'
12
+ rescue => e
13
+ expect(e.message).not_to be nil
14
+ end
15
+ end
16
+ end
17
+
18
+ describe '#jira_api_url' do
19
+ def jira_api_url(url=nil, user=nil, pass=nil)
20
+ jrep.send(:jira_api_url, url, user, pass)
21
+ end
22
+
23
+ it 'is an http url' do
24
+ url = jira_api_url
25
+ expect(url).not_to be nil
26
+ expect(url).to start_with 'http'
27
+ end
28
+
29
+ it 'uses rest api' do
30
+ expect(jira_api_url).to include('rest/api/2/search')
31
+ end
32
+
33
+ context 'when we use url, username and password' do
34
+ let(:usr) { 'admin_username' }
35
+ let(:url) { 'jira.mycompany.url' }
36
+ let(:pas) { '*****' }
37
+ it 'contains url, username and password' do
38
+ url = jira_api_url(url, usr, pas)
39
+ expect(url).to include(url)
40
+ expect(url).to include(usr)
41
+ expect(url).to include(pas)
42
+ end
43
+ end
44
+ end
45
+ end
46
+
47
+ describe '#queries' do
48
+ let(:usr) { 'JohnDoe' }
49
+ let(:from) { '-3w' }
50
+ let(:till) { '-1w' }
51
+
52
+ mocked_rep = Reporter.new('url', 'usr', 'pas')
53
+
54
+ before(:example) do
55
+ allow(mocked_rep).to receive(:query_issues) do |arg|
56
+ arg
57
+ end
58
+ end
59
+
60
+ describe '#created' do
61
+ it 'has from, till and reporter' do
62
+ expect(mocked_rep.created(usr, from, till)).to eql(
63
+ "jql=created>=#{from} AND created<=#{till} AND reporter=#{usr}"
64
+ )
65
+ end
66
+ it 'has from and reporter' do
67
+ expect(mocked_rep.created(usr, from)).to eql(
68
+ "jql=created>=#{from} AND reporter=#{usr}"
69
+ )
70
+ end
71
+ it 'has till and reporter' do
72
+ expect(mocked_rep.created(usr, nil, till)).to eql(
73
+ "jql=created<=#{till} AND reporter=#{usr}"
74
+ )
75
+ end
76
+ it 'has only reporter' do
77
+ expect(mocked_rep.created(usr)).to eql(
78
+ "jql=reporter=#{usr}"
79
+ )
80
+ end
81
+ it 'has not parameters' do
82
+ expect(mocked_rep.created(nil)).to eql(
83
+ "jql=reporter="
84
+ )
85
+ end
86
+ end
87
+
88
+ describe '#resolved' do
89
+ it 'has from, till and reporter' do
90
+ expect(mocked_rep.resolved(usr, from, till)).to eql(
91
+ "jql=resolved>=#{from} AND resolved<=#{till} AND 'First Resolution User'=#{usr}"
92
+ )
93
+ end
94
+ it 'has from and reporter' do
95
+ expect(mocked_rep.resolved(usr, from)).to eql(
96
+ "jql=resolved>=#{from} AND 'First Resolution User'=#{usr}"
97
+ )
98
+ end
99
+ it 'has till and reporter' do
100
+ expect(mocked_rep.resolved(usr, nil, till)).to eql(
101
+ "jql=resolved<=#{till} AND 'First Resolution User'=#{usr}"
102
+ )
103
+ end
104
+ it 'has only reporter' do
105
+ expect(mocked_rep.resolved(usr)).to eql(
106
+ "jql='First Resolution User'=#{usr}"
107
+ )
108
+ end
109
+ it 'has not parameters' do
110
+ expect(mocked_rep.resolved(nil)).to eql(
111
+ "jql='First Resolution User'="
112
+ )
113
+ end
114
+ end
115
+
116
+ describe '#reopened' do
117
+ it 'has from, till and reporter' do
118
+ expect(mocked_rep.reopened(usr, from, till)).to eql(
119
+ "jql='First Reopened Date'>=#{from} "\
120
+ "AND 'First Reopened Date'<=#{till} "\
121
+ "AND 'First Reopened User'=#{usr}"
122
+ )
123
+ end
124
+ it 'has from and reporter' do
125
+ expect(mocked_rep.reopened(usr, from)).to eql(
126
+ "jql='First Reopened Date'>=#{from} "\
127
+ "AND 'First Reopened User'=#{usr}"
128
+ )
129
+ end
130
+ it 'has till and reporter' do
131
+ expect(mocked_rep.reopened(usr, nil, till)).to eql(
132
+ "jql='First Reopened Date'<=#{till} "\
133
+ "AND 'First Reopened User'=#{usr}"
134
+ )
135
+ end
136
+ it 'has only reporter' do
137
+ expect(mocked_rep.reopened(usr)).to eql(
138
+ "jql='First Reopened User'=#{usr}"
139
+ )
140
+ end
141
+ it 'has not parameters' do
142
+ expect(mocked_rep.reopened(nil)).to eql(
143
+ "jql='First Reopened User'="
144
+ )
145
+ end
146
+ end
147
+
148
+ describe '#closed' do
149
+ it 'has from, till and reporter' do
150
+ expect(mocked_rep.closed(usr, from, till)).to eql(
151
+ "jql='First Closed Date'>=#{from} "\
152
+ "AND 'First Closed Date'<=#{till} "\
153
+ "AND 'First Closed User'=#{usr}"
154
+ )
155
+ end
156
+ it 'has from and reporter' do
157
+ expect(mocked_rep.closed(usr, from)).to eql(
158
+ "jql='First Closed Date'>=#{from} "\
159
+ "AND 'First Closed User'=#{usr}"
160
+ )
161
+ end
162
+ it 'has till and reporter' do
163
+ expect(mocked_rep.closed(usr, nil, till)).to eql(
164
+ "jql='First Closed Date'<=#{till} "\
165
+ "AND 'First Closed User'=#{usr}"
166
+ )
167
+ end
168
+ it 'has only reporter' do
169
+ expect(mocked_rep.closed(usr)).to eql(
170
+ "jql='First Closed User'=#{usr}"
171
+ )
172
+ end
173
+ it 'has not parameters' do
174
+ expect(mocked_rep.closed(nil)).to eql(
175
+ "jql='First Closed User'="
176
+ )
177
+ end
178
+ end
179
+ end
180
+
181
+ end
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jira_report
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vitalii Elenhaupt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-06 00:00:00.000000000 Z
11
+ date: 2015-02-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: inifile
14
+ name: parseconfig
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '3.0'
19
+ version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '3.0'
26
+ version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rest-client
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -99,9 +99,13 @@ files:
99
99
  - jira_report.gemspec
100
100
  - lib/jira_report.rb
101
101
  - lib/jira_report/cli.rb
102
- - lib/jira_report/settings.rb
102
+ - lib/jira_report/config_loader.rb
103
+ - lib/jira_report/options.rb
104
+ - lib/jira_report/reporter.rb
103
105
  - lib/jira_report/version.rb
104
- - spec/jira_report_spec.rb
106
+ - spec/jira_report/config_loader_spec.rb
107
+ - spec/jira_report/options_spec.rb
108
+ - spec/jira_report/reporter_spec.rb
105
109
  - spec/spec_helper.rb
106
110
  homepage: https://github.com/veelenga/jira_report.git
107
111
  licenses:
@@ -115,7 +119,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
115
119
  requirements:
116
120
  - - ">="
117
121
  - !ruby/object:Gem::Version
118
- version: '0'
122
+ version: 1.9.3
119
123
  required_rubygems_version: !ruby/object:Gem::Requirement
120
124
  requirements:
121
125
  - - ">="
@@ -128,6 +132,8 @@ signing_key:
128
132
  specification_version: 4
129
133
  summary: Jira activity report generator.
130
134
  test_files:
131
- - spec/jira_report_spec.rb
135
+ - spec/jira_report/config_loader_spec.rb
136
+ - spec/jira_report/options_spec.rb
137
+ - spec/jira_report/reporter_spec.rb
132
138
  - spec/spec_helper.rb
133
139
  has_rdoc:
@@ -1,48 +0,0 @@
1
- require 'inifile'
2
- require 'io/console'
3
-
4
- # Initializes JiraReport settings.
5
- module JiraReport
6
- class Settings
7
- attr_reader :username, :password, :url,\
8
- :period_from, :period_till
9
-
10
- def initialize(path)
11
- read(path)
12
- end
13
-
14
- private
15
-
16
- def read(path)
17
- loaded = IniFile.load(File.expand_path(path))
18
-
19
- global = loaded[:global] if loaded
20
- global ||= {}
21
-
22
- @url = global['url']
23
- @username = global['username']
24
- @password = global['password']
25
- @period_from = global['period_from']
26
- @period_till = global['period_till']
27
-
28
- @url = ask('Jira url in [jira.company.com] format: ') unless @url
29
- @username = ask('Jira username: ') unless @username
30
- @password = ask('Jira password: '){
31
- STDIN.noecho(&:gets).chomp!
32
- } unless @password
33
- @period_from = '-1w' unless @period_from
34
- @period_till = 'now()' unless @period_till
35
-
36
- # TODO: attributes verification
37
- end
38
-
39
- def ask(message, &block)
40
- print message
41
- if block
42
- yield block
43
- else
44
- gets.chomp!
45
- end
46
- end
47
- end
48
- end
@@ -1,64 +0,0 @@
1
- require 'spec_helper'
2
-
3
- module JiraReport
4
-
5
- class InitSet
6
- attr_accessor :url,
7
- :username, :password,
8
- :period_from, :period_till
9
- end
10
-
11
- describe JiraReport do
12
- let(:init) { InitSet.new }
13
- let(:jrep) { JiraReport.new(init, 'username') }
14
-
15
- describe '#jira_search_url' do
16
- def jira_search_url(url=nil, user=nil, pass=nil)
17
- jrep.send(:jira_search_url, url, user, pass)
18
- end
19
-
20
- it 'is an http url' do
21
- url = jira_search_url
22
- expect(url).not_to be nil
23
- expect(url).to start_with 'http'
24
- end
25
-
26
- it 'uses rest api' do
27
- expect(jira_search_url).to include('rest/api/2/search')
28
- end
29
-
30
- context 'when we use url and username' do
31
- let(:usr) { 'admin_username' }
32
- let(:url) { 'jira.mycompany.url' }
33
- it 'contains url and username' do
34
- url = jira_search_url(url, usr, nil)
35
- expect(url).to include(url)
36
- expect(url).to include(usr)
37
- end
38
- end
39
-
40
- describe '#jql_*' do
41
- describe '#jql_created' do
42
- it 'returns query' do
43
- expect(jrep.send(:jql_created)).not_to be nil
44
- end
45
- end
46
- describe '#jql_resolved' do
47
- it 'returns query' do
48
- expect(jrep.send(:jql_resolved)).not_to be nil
49
- end
50
- end
51
- describe '#jql_closed' do
52
- it 'returns query' do
53
- expect(jrep.send(:jql_closed)).not_to be nil
54
- end
55
- end
56
- describe '#jql_reopened' do
57
- it 'returns query' do
58
- expect(jrep.send(:jql_reopened)).not_to be nil
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end