fgi 0.2.6.3 → 1.0

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: 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.