fgi 0.2.6.3 → 1.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4cccd7a5b745ba11b6a6b1587d74a6766e0d017c
4
- data.tar.gz: 580b1cc6fcbbefb0d551904de1027e849f8328dd
3
+ metadata.gz: 02d08a9e357b68fd81e265725782dcc98328267a
4
+ data.tar.gz: 5c4fae2bb99e2871d2488898ea666cf0fff0d7d5
5
5
  SHA512:
6
- metadata.gz: 077e1f8ace7e2f006e6429603836af1934219c9dc5811f63676794340700ed819d4ac03e65cdbfdbd4bdf8480219b21e8c30a40d17082e7c77d2ef2f1b126236
7
- data.tar.gz: edc81dfbb587b2990e22e341f34adeaa97589d931779fef12371107c7c1ef7c7a15e167c5dcfe6eb1bf38a184fbc15430f5f1e9926266956b7efd8403e3ff2fe
6
+ metadata.gz: e279751a9e0e1f5062a7ed1348bdef87c458a2d000ca0d0249db511abfdaf578a88d9d5790f48dbd6c98fe28aca6369205c366eac05f593dbf649f78340be990
7
+ data.tar.gz: 1ef9c20120cfe320029c7e7298f5763c6ca8b9393b7ca73fb0eef1886132d0b7053191e8c3ae8a620604a28ea7508a503d50ba9f66d21288c3ee3d1bd70610f4
data/bin/fgi ADDED
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
3
+
4
+ require_relative '../lib/fgi'
5
+
6
+ argv = ARGV
7
+
8
+ # ----------------------------- #
9
+ # FGI CMD DOC #
10
+ # ----------------------------- #
11
+
12
+ options = {}
13
+ options_parser = OptionParser.new do |fgi|
14
+ fgi.banner = 'Usage: fgi COMMAND [OPTION]'
15
+ fgi.separator ''
16
+ fgi.separator 'Commands'
17
+ fgi.separator ' config : run the fgi configurator.'
18
+ fgi.separator ' token [TOKEN] : define the new user token.'
19
+ fgi.separator ' new [ISSUE_NAME] : create the issue with the given name.'
20
+ fgi.separator ' ... more comming soon ...'
21
+ fgi.separator ''
22
+ fgi.separator 'Options'
23
+
24
+ fgi.on('-e', '--estimate ESTIMATION', 'How many time do you think you will spend on this issue ?') do |estimate|
25
+ options[:estimate] = estimate
26
+ end
27
+
28
+ fgi.on('-h', '--help', 'Display the FGI manual') do
29
+ puts options_parser
30
+ end
31
+ end
32
+ options_parser.parse!
33
+
34
+ # ---------------------------- #
35
+ # DISPATCHER #
36
+ # ---------------------------- #
37
+
38
+ def get_full_issue_title(argv)
39
+ return nil if argv[1].nil?
40
+ length = argv.length
41
+ argv[1..length].join(' ')
42
+ end
43
+
44
+ case argv[0]
45
+ when 'config'
46
+ Fgi::Configuration.new_config
47
+ when 'new'
48
+ Fgi.configured?
49
+ if argv[1].start_with?('-')
50
+ puts %q(You can't begin your issue's title with '-')
51
+ exit!
52
+ end
53
+ title = get_full_issue_title(argv)
54
+ Fgi::GitService.create_issue(title)
55
+ when 'token'
56
+ Fgi.configured?
57
+ Fgi::Tokens.add_token(argv[1])
58
+ else
59
+ puts options_parser
60
+ end
data/lib/fgi.rb CHANGED
@@ -1,18 +1,31 @@
1
- #!/usr/bin/env ruby
1
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
2
+ module Fgi
2
3
 
3
- require 'yaml'
4
- require 'json'
4
+ require 'net/http'
5
+ require 'optparse'
6
+ require 'json'
7
+ require 'yaml'
8
+ require 'uri'
5
9
 
6
- module Fgi
7
- class << self
10
+ require_relative 'fgi/git_services/gitlab'
11
+ require_relative 'fgi/http_requests'
12
+ require_relative 'fgi/tokens'
13
+ require_relative 'fgi/configuration'
14
+ require_relative 'fgi/git_service'
15
+
16
+ # Define const variables if fgi config files exists
17
+ # otherwise ask for configuration
18
+ if File.exists?('.config.fgi.yml')
19
+ CONFIG = YAML.load_file('.config.fgi.yml')
20
+ git_service = CONFIG[:git_service_class].new
21
+ if File.exists?("#{Dir.home}/.tokens.fgi.yml")
22
+ TOKEN = YAML.load_file("#{Dir.home}/.tokens.fgi.yml")[git_service.to_sym]
23
+ end
8
24
  end
9
- require_relative 'fgi/config'
10
- require_relative 'fgi/version'
11
- require_relative 'fgi/executor'
12
- require_relative 'fgi/html_request'
13
- require_relative 'fgi/helper'
14
- require_relative 'fgi/configurator'
15
- require_relative 'fgi/generate_file'
16
25
 
17
- CONFIG_FILE = '.fast_gitlab_issues.yml'
26
+ def self.configured?
27
+ return if File.exists?('.config.fgi.yml')
28
+ puts "\nThere is no FGI configuration file on this project. Please run 'fgi config'.\n\n"
29
+ exit!
30
+ end
18
31
  end
@@ -0,0 +1,196 @@
1
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
2
+ module Fgi
3
+ class Configuration
4
+ class << self
5
+ include HttpRequests
6
+
7
+ # Launch the process to create the fresh project fgi config file
8
+ def new_config
9
+ puts '####################################################################'
10
+ puts '## Welcome to Fast Gitlab Issues configuration ##'
11
+ puts "####################################################################\n\n"
12
+
13
+ # -------------------------- #
14
+ # CHECKERS #
15
+ # -------------------------- #
16
+
17
+ git_directory?
18
+ already_configured?
19
+
20
+ # -------------------------- #
21
+ # INITIALIZERS #
22
+ # -------------------------- #
23
+
24
+
25
+ # The hash that will contain the project's fgi configuration to save as yml
26
+ # It will contain :
27
+ # :url
28
+ # :routes
29
+ # :project_id
30
+ # :project_slug
31
+ config = {}
32
+
33
+ config[:git_service_class] = define_git_service
34
+ config[:url] = save_git_url
35
+
36
+ # Instanciation of the Git service class
37
+ git_service = config[:git_service_class].new(config: config)
38
+ config[:git_service] = git_service.to_sym
39
+ user_token = save_user_token(git_service)
40
+ project_name_and_id = define_project_name_and_id(git_service, user_token)
41
+ config = config.merge(project_name_and_id)
42
+
43
+ # -------------------------- #
44
+ # CREATORS #
45
+ # -------------------------- #
46
+
47
+ Fgi::Tokens.create_user_tokens_file(config[:git_service], user_token)
48
+ create_fgi_config_file(config)
49
+ end
50
+
51
+ private
52
+
53
+ # Check if we are in a git repository. Exit FGI if not.
54
+ def git_directory?
55
+ unless Dir.exists?('.git')
56
+ puts 'You are not in a git project repository.'
57
+ exit!
58
+ end
59
+ end
60
+
61
+ # Check if FGI has already been configured. Exit FGI if not.
62
+ def already_configured?
63
+ if File.exists?('.config.fgi.yml')
64
+ puts 'There is already a FGI config on this project.'
65
+ exit!
66
+ end
67
+ end
68
+
69
+ # Ask the user to shoose the project's Git service
70
+ # @return [Class] the project's Git service class
71
+ def define_git_service
72
+ puts "\nPlease insert the number of the used Git service :"
73
+ puts '--------------------------------------------------'
74
+
75
+ # Get the list of the Git service for which we provide FGI at the moment
76
+ git_services = Fgi::GitService.services
77
+ # Display theses services to let the user choose the project's one
78
+ git_services.each_with_index do |service, index|
79
+ puts "#{index+1} : #{service.capitalize}"
80
+ end
81
+ puts "... More soon ..."
82
+
83
+ begin
84
+ input = STDIN.gets.chomp
85
+ exit! if input == 'quit'
86
+ # Convert the string input to an integer
87
+ input = input.to_i
88
+ # If the input isn't out of range...
89
+ if (1..git_services.count).include?(input)
90
+ # Set a variable with the Git service name for displays
91
+ @git_service = git_services[input-1].capitalize
92
+ Fgi::GitServices.const_get(@git_service)
93
+ else
94
+ puts "\nSorry, the option is out of range. Try again :"
95
+ define_git_service
96
+ end
97
+ rescue Interrupt => int
98
+ exit!
99
+ end
100
+ end
101
+
102
+ # Ask for the Git service url.
103
+ # @return [String] the well formatted Git service URL
104
+ def save_git_url
105
+ puts "\nPlease enter your #{@git_service} url :"
106
+ puts 'example: http://gitlab.example.com/'
107
+ puts '-----------------------------------'
108
+
109
+ begin
110
+ input = STDIN.gets.chomp
111
+ exit! if input == 'quit'
112
+ # force scheme if not specified
113
+ input = "http://#{input}" if !input.start_with?('http://', 'https://')
114
+ # Call the entered url to know if it exist or not.
115
+ # If not, would raise an exception
116
+ get(url: input)
117
+ input
118
+ rescue Interrupt => int
119
+ exit!
120
+ rescue Exception => e
121
+ puts "\nOops, seems to be a bad url. Try again or quit (quit)"
122
+ save_git_url
123
+ end
124
+ end
125
+
126
+ # Ask for the user for his Git service token
127
+ # @param git_service [Class] the current project's git service class
128
+ # @return [String] the user Git service token
129
+ def save_user_token(git_service)
130
+ token = Fgi::Tokens.get_token(git_service)
131
+ return token unless token.nil?
132
+ save_user_token(git_service)
133
+ end
134
+
135
+ # Ask the user to search for the project and to select the correct one.
136
+ # @param git_service [Class] the current project's git service class
137
+ # @param user_token [String] the user's token
138
+ # @return [Hash<String>] the hash which contain the project's slugname and id
139
+ def define_project_name_and_id(git_service, user_token)
140
+ puts "\nPlease enter the name of the current project :"
141
+ puts '----------------------------------------------'
142
+
143
+ begin
144
+ input = STDIN.gets.chomp
145
+ exit! if input == 'quit'
146
+
147
+ url = "#{git_service.routes[:search_projects]}#{input}"
148
+ response = get(url: url, headers: { git_service.token_header => user_token })
149
+
150
+ if response[:status] == '200' && !response[:body].empty?
151
+ puts "\nFound #{response[:body].count} match(es):"
152
+ response[:body].each_with_index do |project, index|
153
+ puts "#{index+1} - #{project['name_with_namespace']}"
154
+ end
155
+
156
+ validate_project_choice(response[:body])
157
+
158
+ else
159
+ puts "\nOops, we couldn't find a project called #{input}. Try again or quit (quit) :"
160
+ puts '-------------------------------------------------------------------'+('-'*input.length) # Don't be upset, i'm a perfectionist <3
161
+ define_project_name_and_id(git_service, user_token)
162
+ end
163
+ rescue Interrupt => int
164
+ exit!
165
+ end
166
+ end
167
+
168
+
169
+ def validate_project_choice(response_body)
170
+ puts "\nPlease insert the number of the current project :"
171
+ puts '---------------------------------------------------'
172
+ input = STDIN.gets.chomp
173
+ exit! if input == 'quit'
174
+ input = input.to_i
175
+ if (1..response_body.count).include?(input)
176
+ {
177
+ project_slug: response_body[input - 1]['path_with_namespace'],
178
+ project_id: response_body[input - 1]['id']
179
+ }
180
+ else
181
+ puts "\nSorry, the option is out of range. Try again :"
182
+ validate_project_choice(response_body)
183
+ end
184
+ end
185
+
186
+ def create_fgi_config_file(config)
187
+ File.open('.config.fgi.yml', 'w') { |f| f.write config.to_yaml }
188
+
189
+ puts "\nYou are now set to work on #{config[:project_slug]}."
190
+ puts 'Your configuration has been saved to .config.fgi.yml, enjoy !'
191
+ puts "\n#############################################################"
192
+ end
193
+
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,65 @@
1
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
2
+ module Fgi
3
+ class GitService
4
+ class << self
5
+ include HttpRequests
6
+
7
+ def services
8
+ services = []
9
+ Dir.entries("#{File.dirname(__FILE__)}/git_services").each do |service|
10
+ services << service.gsub(/.rb/, '').to_sym unless %w(. ..).include?(service)
11
+ end
12
+ services
13
+ end
14
+
15
+ def create_issue(title)
16
+ git_service = CONFIG[:git_service_class].new
17
+ title = get_issue_title if title.nil?
18
+ description = get_issue_description
19
+
20
+ headers = { git_service.token_header => TOKEN, 'Content-Type': 'application/json' }
21
+ url_with_querystring = "#{git_service.routes[:issues]}?title=#{URI.encode(title)}&description=#{URI.encode(description)}"
22
+
23
+ response = post(url: url_with_querystring, headers: headers)
24
+
25
+ post_issue_display(JSON.parse(response[:body]))
26
+ end
27
+
28
+ private
29
+
30
+ def get_issue_description
31
+ puts "\nWrite your issue description right bellow (save and quit with CTRL+D) :"
32
+ puts "-----------------------------------------------------------------------\n\n"
33
+ begin
34
+ STDIN.read
35
+ rescue Interrupt => int
36
+ puts %q"Why did you killed me ? :'("
37
+ exit!
38
+ end
39
+ end
40
+
41
+ def get_issue_title
42
+ puts "\nWhat if your issue title :"
43
+ puts "--------------------------\n\n"
44
+ begin
45
+ STDIN.gets.chomp
46
+ rescue Interrupt => int
47
+ puts %q"Why did you killed me ? :'("
48
+ exit!
49
+ end
50
+ end
51
+
52
+ def post_issue_display(response)
53
+ if !response['iid'].nil?
54
+ puts 'Your issue has been successfully created.'
55
+ puts 'To view it, please follow the link bellow :'
56
+ puts "\n#{CONFIG[:url]}/#{CONFIG[:project_slug]}/issues/#{response['iid']}"
57
+ puts "\nThank you for using Fast Gitlab Issues!"
58
+ else
59
+ puts %q(Your issue couldn't be created. Check your FGI configuration.)
60
+ end
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,38 @@
1
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
2
+ module Fgi
3
+ module GitServices
4
+ class Gitlab
5
+
6
+ def initialize(config: CONFIG)
7
+ @version = 'v4'
8
+ @token_header = 'PRIVATE-TOKEN'
9
+ @routes = {
10
+ projects: "#{config[:url]}/api/#{@version}/projects",
11
+ search_projects: "#{config[:url]}/api/#{@version}/projects?search=",
12
+ issues: "#{config[:url]}/api/#{@version}/projects/#{config[:project_id]}/issues"
13
+ }
14
+ end
15
+
16
+ def version
17
+ @version
18
+ end
19
+
20
+ def token_header
21
+ @token_header
22
+ end
23
+
24
+ def routes
25
+ @routes
26
+ end
27
+
28
+ def to_sym
29
+ :gitlab
30
+ end
31
+
32
+ def to_s
33
+ 'Gitlab'
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ # @author Matthieu Gourvénec <matthieu.gourvenec@gmail.com>
2
+ module Fgi
3
+ module HttpRequests
4
+
5
+ # Generic method to GET requests
6
+ # @param url [String] the given Git service API url for GET request
7
+ # @param headers [Hash] the headers to set for the request
8
+ # @return [String] the received response from the Git service API
9
+ def get(url:, headers: nil)
10
+ http_request(verb: :get, url: url, headers: headers)
11
+ end
12
+
13
+ # Generic method to POST requests
14
+ # @param url [String] the given Git service API url for POST request
15
+ # @param headers [Hash] the headers to set for the request
16
+ # @param body [Hash] the body to set for the request
17
+ # @return [String] the received response from the Git service API
18
+ def post(url:, headers: nil, body: nil)
19
+ http_request(verb: :post, url: url, headers: headers)
20
+ end
21
+
22
+ private
23
+
24
+ # Generic method for HTTP requests
25
+ # @param url [String] the given Git service API url for a HTTP request
26
+ # @param headers [Hash] the headers to set for the request
27
+ # @param body [Hash] the body to set for the request
28
+ # @return [String] the received response from the Git service API
29
+ def http_request(verb:, url:, headers: nil, body: nil)
30
+ uri = URI.parse(url)
31
+ req = case verb
32
+ when :get
33
+ Net::HTTP::Get.new(url)
34
+ when :post
35
+ Net::HTTP::Post.new(url)
36
+ end
37
+
38
+ # Set headers if given
39
+ headers.each { |k, v| req[k] = v } unless headers.nil?
40
+ # Set body if given
41
+ req.body = body.to_json unless body.nil?
42
+
43
+ res = Net::HTTP.start(uri.host, uri.port) do |http|
44
+ http.request(req)
45
+ end
46
+
47
+ if res.code == '200'
48
+ { status: '200', body: JSON.parse(res.body) }
49
+ else
50
+ { status: res.code, body: res.body }
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,66 @@
1
+ # @author Matthieu Gourvénec <gourve_m@modulotech.fr>
2
+ module Fgi
3
+ class Tokens
4
+ class << self
5
+ include HttpRequests
6
+
7
+ # @param git_service_name [String] the git service to associate a token to
8
+ # @param token [String] the token to associate to the git service
9
+ def create_user_tokens_file(git_service, token)
10
+ if File.exists?("#{Dir.home}/.tokens.fgi.yml")
11
+ tokens = YAML.load_file("#{Dir.home}/.tokens.fgi.yml")
12
+ tokens[git_service] = token
13
+ else
14
+ tokens = { git_service => token }
15
+ end
16
+ # Shouldn't we define some access restrictions on this file ?
17
+ File.open("#{Dir.home}/.tokens.fgi.yml", 'w') { |f| f.write(tokens.to_yaml) }
18
+ end
19
+
20
+ # Add a new token association for the user's fgi configuration
21
+ # @param token [String] the token to associate to the git service
22
+ def add_token(token)
23
+ git_service = CONFIG[:git_service_class].new
24
+ token = get_token(git_service) if token.nil?
25
+ if token_valid?(git_service, token)
26
+ create_user_tokens_file(CONFIG[:git_service], token)
27
+ puts "\nYour #{git_service} token has been successfully added !\n\n"
28
+ else
29
+ puts "\nOops, seems to be an invalid token. Try again.\n\n"
30
+ exit!
31
+ end
32
+ end
33
+
34
+ # @param git_service [Class] the current project's git service class
35
+ # @return [String] the current token associated to the project's git service
36
+ # @return [NilClass] if there is no token associated to the project's git service
37
+ def get_token(git_service)
38
+ if File.exists?("#{Dir.home}/.tokens.fgi.yml")
39
+ tokens = YAML.load_file("#{Dir.home}/.tokens.fgi.yml")
40
+ tokens[git_service.to_sym]
41
+ else
42
+ puts "\nPlease enter your #{git_service.to_s} token :"
43
+ puts '(use `fgi --help` to check how to get your token)'
44
+ puts '-------------------------------------------------'
45
+ begin
46
+ token = STDIN.gets.chomp
47
+ exit! if token == 'quit'
48
+ return token if token_valid?(git_service, token)
49
+ nil
50
+ rescue Interrupt => int
51
+ exit!
52
+ end
53
+ end
54
+ end
55
+
56
+ # @param git_service [Class] the current project's git service class
57
+ # @param token [String] the token to check the validity
58
+ # @return [Boolean] true if the token is valid, false otherwise
59
+ def token_valid?(git_service, token)
60
+ response = get(url: git_service.routes[:projects], headers: { git_service.token_header => token })
61
+ response[:status] == '200'
62
+ end
63
+
64
+ end
65
+ end
66
+ end
metadata CHANGED
@@ -1,16 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fgi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6.3
4
+ version: '1.0'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Philibin
8
- - Pedro Coutinho
9
8
  - Matthieu Gourvénec
10
9
  autorequire:
11
- bindir: exe
10
+ bindir: bin
12
11
  cert_chain: []
13
- date: 2017-05-24 00:00:00.000000000 Z
12
+ date: 2017-08-17 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: bundler
@@ -54,30 +53,22 @@ dependencies:
54
53
  - - "~>"
55
54
  - !ruby/object:Gem::Version
56
55
  version: '3.0'
57
- description: Fast Gitlab Issues.
56
+ description: Fast Git Issues.
58
57
  email:
59
58
  - philib_j@modulotech.fr
59
+ - gourve_m@modulotech.fr
60
60
  executables:
61
61
  - fgi
62
62
  extensions: []
63
63
  extra_rdoc_files: []
64
64
  files:
65
- - Gemfile
66
- - README.md
67
- - Rakefile
68
- - bin/console
69
- - bin/setup
70
- - exe/fgi
71
- - fgi.gemspec
65
+ - bin/fgi
72
66
  - lib/fgi.rb
73
- - lib/fgi/config.rb
74
- - lib/fgi/configurator.rb
75
- - lib/fgi/executor.rb
76
- - lib/fgi/generate_file.rb
77
- - lib/fgi/helper.rb
78
- - lib/fgi/html_request.rb
79
- - lib/fgi/version.rb
80
- - temp.txt
67
+ - lib/fgi/configuration.rb
68
+ - lib/fgi/git_service.rb
69
+ - lib/fgi/git_services/gitlab.rb
70
+ - lib/fgi/http_requests.rb
71
+ - lib/fgi/tokens.rb
81
72
  homepage: https://www.modulotech.fr
82
73
  licenses: []
83
74
  metadata: {}
@@ -97,8 +88,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
88
  version: '0'
98
89
  requirements: []
99
90
  rubyforge_project:
100
- rubygems_version: 2.5.1
91
+ rubygems_version: 2.6.11
101
92
  signing_key:
102
93
  specification_version: 4
103
- summary: CLI for gitlab.
94
+ summary: Process and workflow simplifier for git projects.
104
95
  test_files: []
data/Gemfile DELETED
@@ -1,4 +0,0 @@
1
- source 'https://rubygems.org'
2
-
3
- # Specify your gem's dependencies in fgi.gemspec
4
- gemspec
data/README.md DELETED
@@ -1,35 +0,0 @@
1
- # Fgi
2
-
3
- ## Welcome to Fast Gitlab Issues!
4
-
5
- Fast Gitlab Issues, aka Fgi, is a command line issue creation tool for Gitlab v8.8+.
6
-
7
- To install, add the following to your project's Gemfile:
8
-
9
- ```ruby
10
- gem 'fgi', git: 'https://github.com/moduloTech/fast-gitlab-issues.git'
11
- ```
12
-
13
- And run `bundle install`.
14
-
15
- After it finishes, run `$ fgi --config` if the gem is new to the project, or run `$ fgi --token <token>` if you are new to the project and fgi was previously installed.
16
-
17
- You can create your token from Gitlab -> Settings -> Access Tokens
18
- From then on, create your issues from the console:
19
-
20
- ```sh
21
- $ fgi My awesome title goes here
22
- ```
23
-
24
- This will open our default text editor (currently hardcoded to Vim) so you can provide a description, and when you close, it will create an issue on Gitlab. A link to the new issue will be provided if you want to check it out.
25
-
26
- The following commands are currently supported:
27
-
28
- $ fgi \<title\> \# initiates the process to create a gitlab issue
29
- $ fgi --help \# opens this help menu
30
- $ fgi --config \# starts the configuration wizard
31
- $ fgi --token \<token\> \# saves the private gitlab token to a file and adds it to .gitignore
32
-
33
- The config will ask you for your gitlab access token (you can get it from AF2) and the project URL from gitlab.
34
-
35
- Any bugs/requests please open an issue, feel free to use fgi to do so!
data/Rakefile DELETED
@@ -1,6 +0,0 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
3
-
4
- RSpec::Core::RakeTask.new(:spec)
5
-
6
- task :default => :spec
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "fgi"
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/setup DELETED
@@ -1,8 +0,0 @@
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/exe/fgi DELETED
@@ -1,44 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'open3'
4
- require 'uri'
5
- require 'net/http'
6
- require_relative '../lib/fgi'
7
-
8
- # extract core logic from here into the gem bin
9
- module Fgi
10
- class Command
11
- def initialize(content)
12
- # convert title into a string we can use in a curl request
13
- content = content.join(' ')
14
- case
15
- when content.empty?
16
- Fgi::Helper.run
17
- when content.match(/--help/)
18
- Fgi::Helper.run
19
- when content.match(/--config/)
20
- Fgi::Configurator.run
21
- when content.match(/--token/)
22
- Fgi::Configurator.validate_and_save_gitlab_token(content.strip.split(' ').last)
23
- else
24
- create_issue(content)
25
- end
26
- end
27
-
28
- # Get the issue's description and initiate its creation
29
- # @param title [String] the issue's title
30
- def create_issue(title)
31
- puts "\nWrite your issue description right bellow (save and quit with CTRL+D) :"
32
- puts "---------------------------------------------------------------------\n\n"
33
- begin
34
- description = STDIN.read
35
- rescue Interrupt => int
36
- puts %q[Why did you killed me ? :'(]
37
- exit!
38
- end
39
- Fgi::Executor.new.process_data(title, description)
40
- end
41
- end
42
- end
43
-
44
- Fgi::Command.new(ARGV)
@@ -1,26 +0,0 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'fgi/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = 'fgi'
8
- spec.version = Fgi::VERSION
9
- spec.authors = ['Julien Philibin', 'Pedro Coutinho', 'Matthieu Gourvénec']
10
- spec.email = ['philib_j@modulotech.fr']
11
-
12
- spec.summary = 'CLI for gitlab.'
13
- spec.description = 'Fast Gitlab Issues.'
14
- spec.homepage = 'https://www.modulotech.fr'
15
-
16
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
17
- f.match(%r{^(test|spec|features)/})
18
- end
19
- spec.bindir = 'exe'
20
- spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
21
- spec.require_paths = ['lib']
22
-
23
- spec.add_development_dependency 'bundler', '~> 1.13'
24
- spec.add_development_dependency 'rake', '~> 10.0'
25
- spec.add_development_dependency 'rspec', '~> 3.0'
26
- end
@@ -1,33 +0,0 @@
1
- module Fgi
2
- class Config
3
- class << self
4
- def load(source)
5
- @config = { :url => nil, :project_gitlab_id => nil, :project_namespaced => nil }
6
-
7
- Fgi::GenerateFile.new(@config) if !File.exist?(source)
8
- Fgi::GenerateFile.token if !File.exist?('.gitlab_access_token')
9
-
10
- config = YAML.load_file(source)
11
- token = File.open(".gitlab_access_token", "rb").read
12
- @config.merge! config if config
13
- @config[:token] = token
14
- end
15
-
16
- def include?(key)
17
- @config.include?(key)
18
- end
19
-
20
- def [](key)
21
- @config[key]
22
- end
23
-
24
- def to_yaml
25
- @config.to_yaml
26
- end
27
-
28
- def current
29
- @config ||= { :url => nil, :project_gitlab_id => nil, :project_namespaced => nil }
30
- end
31
- end
32
- end
33
- end
@@ -1,162 +0,0 @@
1
- module Fgi
2
- class Configurator
3
- class << self
4
-
5
- def run
6
- @config = Fgi::Config.current
7
- is_git_dir?
8
- puts '####################################################################'
9
- puts ' Welcome to Fast Gitlab Issues configuration '
10
- puts "####################################################################\n\n"
11
- puts "#### Enter 'quit' or 'exit' at any time to go back to buisness! ####\n\n"
12
-
13
- puts 'Please enter your Gitlab Url:'
14
- validate_and_save_gitlab_uri
15
-
16
- puts "\nPlease enter your Gitlab access token :"
17
- puts "(You can generate new token from Gitlab -> Settings -> Access Tokens)"
18
- puts '---------------------------------------'
19
- validate_and_save_gitlab_token
20
-
21
- puts "\nPlease enter the name of the current project :"
22
- puts '----------------------------------------------'
23
- search_and_save_project
24
-
25
- File.open('.fast_gitlab_issues.yml', 'w') { |f| f.write @config.to_yaml }
26
- puts "\nYou are now set to work on #{@config[:project_namespaced]}."
27
- puts 'Your configuration has been saved to .fast_gitlab_issues.yml, enjoy !'
28
- puts "\n####################################################################"
29
- end
30
-
31
- def validate_and_save_gitlab_token(inline_token = nil)
32
- begin
33
- @token = if inline_token.nil?
34
- STDIN.gets.chomp
35
- else
36
- set_config
37
- inline_token
38
- end
39
- if %w(quit exit).include?(@token)
40
- puts 'See you back soon !'
41
- exit!
42
- end
43
- rescue Interrupt => int
44
- puts %q[Why did you killed me ? :'(]
45
- exit!
46
- end
47
- @projects_uri = "#{@config[:url]}/api/v4/projects"
48
-
49
- req = Net::HTTP::Get.new(@projects_uri)
50
- req['PRIVATE-TOKEN'] = @token
51
- res = Net::HTTP.start(@uri.hostname, @uri.port) { |http| http.request(req) }
52
-
53
- if res.code == '200'
54
- save_gitlab_token
55
- else
56
- puts "\nOops, seems to be an invalid token. Try again or quit (quit/exit) :"
57
- puts '--------------------------------------------------------------'
58
- validate_and_save_gitlab_token
59
- end
60
- end
61
-
62
- private
63
-
64
- def validate_and_save_gitlab_uri
65
- puts 'example: http://gitlab.example.com/'
66
- puts '-----------------------------------'
67
- begin
68
- input = STDIN.gets.chomp
69
- if %w(quit exit).include?(input)
70
- puts 'See you back soon !'
71
- exit!
72
- end
73
- input = "http://#{input}" if !input.start_with?('http://', 'https://')
74
- @uri = URI.parse("#{input}/")
75
- @config[:url] = "#{@uri.scheme}://#{@uri.host}"
76
- req = Net::HTTP.new(@uri.host, @uri.port)
77
- res = req.request_head(@uri.path)
78
- rescue Interrupt => int
79
- puts %q[Why did you killed me ? :'(]
80
- exit!
81
- rescue Exception => e
82
- puts "\nOops, seems to be a bad url. Try again or quit (quit/exit) :"
83
- validate_and_save_gitlab_uri
84
- end
85
- end
86
-
87
- def save_gitlab_token
88
- File.open('.gitlab_access_token', 'w') { |f| f.write @token }
89
- if File.open('.gitignore').grep(/.gitlab_access_token/).empty?
90
- open('.gitignore', 'a') do |f|
91
- f.puts ''
92
- f.puts '# Gfi secret token for gitlab'
93
- f.puts '.gitlab_access_token'
94
- end
95
- end
96
- puts "\nGitlab secret token successfully saved to file and added to .gitignore."
97
- end
98
-
99
- def search_and_save_project
100
- begin
101
- project_name = STDIN.gets.chomp
102
- if %w(quit exit).include?(project_name)
103
- puts 'See you back soon !'
104
- exit!
105
- end
106
- rescue Interrupt => int
107
- puts %q[Why did you killed me ? :'(]
108
- exit!
109
- end
110
-
111
- req = Net::HTTP::Get.new("#{@projects_uri}?search=#{project_name}")
112
- req['PRIVATE-TOKEN'] = @token
113
- res = Net::HTTP.start(@uri.hostname, @uri.port) { |http| http.request(req) }
114
-
115
- results = JSON.parse(res.body)
116
- if res.code == '200' && !results.empty?
117
- puts "\nFound #{results.count} match(es):"
118
- results.each_with_index do |result, i|
119
- puts "#{i+1} - #{result['name_with_namespace']}"
120
- end
121
- validate_option(results)
122
- else
123
- puts "\nOops, we couldn't find a project called #{project_name}. Try again or quit (quit/exit) :"
124
- puts '-------------------------------------------------------------------'+('-'*project_name.length) # Yes, i'm a perfectionist <3
125
- search_and_save_project
126
- end
127
- end
128
-
129
- def validate_option(results)
130
- puts "\nPlease insert the number of the current project :"
131
- puts '-------------------------------------------------'
132
- begin
133
- option = STDIN.gets.chomp.to_i
134
- rescue Interrupt => int
135
- puts %q[Why did you killed me ? :'(]
136
- exit!
137
- end
138
- if (1..results.length+1).include?(option)
139
- @config[:project_gitlab_id] = results[option - 1]['id']
140
- @config[:project_namespaced] = results[option - 1]['path_with_namespace']
141
- else
142
- puts "\nSorry, the option is out of range. Try again :"
143
- validate_option(results)
144
- end
145
- end
146
-
147
- def set_config
148
- config_file = File.expand_path(CONFIG_FILE)
149
- @config = YAML.load_file(config_file)
150
- @uri = URI.parse(@config[:url])
151
- end
152
-
153
- def is_git_dir?
154
- is_git_directory = Dir.exists?('.git')
155
- if !is_git_directory
156
- puts %q(This doesn't seem to be the root of a git repository, browse to the root of your project and try again.)
157
- return
158
- end
159
- end
160
- end
161
- end
162
- end
@@ -1,11 +0,0 @@
1
- module Fgi
2
- class Executor
3
- def process_data(title, description)
4
- # load config
5
- config = File.expand_path(CONFIG_FILE)
6
- Fgi::Config.load(config)
7
- # curl to server
8
- Fgi::HTMLRequest.new(title, description).push
9
- end
10
- end
11
- end
@@ -1,19 +0,0 @@
1
- module Fgi
2
- class GenerateFile
3
- def initialize(config)
4
- puts "Config file not found. Do you want to create a config file here? (Y/n)"
5
- if STDIN.gets.chomp != 'Y'
6
- puts "Closing...."
7
- raise "Failed to find a configuration file."
8
- else
9
- Fgi::Configurator.run
10
- end
11
- end
12
-
13
- def self.token
14
- puts 'Please provide a Gitlab access token before continuing:'
15
- Fgi::Configurator.validate_and_save_gitlab_token
16
- puts 'Thank you very much, we will now proceed.'
17
- end
18
- end
19
- end
@@ -1,28 +0,0 @@
1
- module Fgi
2
- class Helper
3
- class << self
4
- def run
5
- puts "
6
- Welcome to Fast Gitlab Issues!
7
-
8
- The following commands are currently supported:
9
-
10
- fgi <title> # initiates the process to create a gitlab issue
11
- fgi --help # opens this help menu
12
- fgi --config # starts the configuration wizard
13
- fgi --token <token> # saves the private gitlab token to a file and adds it to .gitignore
14
-
15
- The config will ask you for your gitlab access token (you can get it from AF2) and the project URL from gitlab.
16
-
17
- To create a gitlab issue just type:
18
-
19
- $ fgi My awesome title goes here
20
-
21
- Vim will open so you can write a description, and upon closing, it will be pushed to gitlab.
22
- A success message should then appear.
23
-
24
- "
25
- end
26
- end
27
- end
28
- end
@@ -1,36 +0,0 @@
1
- module Fgi
2
- class HTMLRequest
3
-
4
- def initialize(title, description)
5
- @title = title
6
- @description = description
7
- end
8
-
9
- def push
10
- uri = URI.parse(generate_link)
11
- req = Net::HTTP::Post.new uri
12
- req['PRIVATE-TOKEN'] = Fgi::Config[:token]
13
-
14
- Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
15
- @response = JSON.parse(http.request(req).body)
16
- end
17
-
18
- if !@response['iid'].nil?
19
- puts 'Your issue has been sucessfully created.'
20
- puts 'To view it, please follow the link bellow:'
21
- puts ''
22
- puts "#{Fgi::Config[:url]}/#{Fgi::Config[:project_namespaced]}/issues/#{@response['iid'].to_s}"
23
- puts ''
24
- puts 'Thank you for using Fast Gitlab Issues!'
25
- else
26
- puts %q(I'm not really sure what happened, but I believe something went wrong.)
27
- puts 'CALL HELP!!!'
28
- end
29
- end
30
-
31
- def generate_link
32
- Fgi::Config[:url] + '/api/v4/projects/' + Fgi::Config[:project_gitlab_id].to_s + '/issues?title=' + URI.encode(@title) + '&description=' + URI.encode(@description)
33
- end
34
-
35
- end
36
- end
@@ -1,3 +0,0 @@
1
- module Fgi
2
- VERSION = "0.2.6.3"
3
- end
data/temp.txt DELETED
@@ -1 +0,0 @@
1
- Some description.