jfh-gitlab-cli 1.0.0.pre.rc.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "cli/version"
4
+ require_relative "projects/projects"
5
+
6
+ ##
7
+ # Main module for all GEMs
8
+ module Jfh
9
+ ##
10
+ # This is the main module for this project
11
+ module Gitlab
12
+ ##
13
+ # The commandline modul
14
+ #
15
+ # It provide the public interface, with following member
16
+ # * version
17
+ # * list_projects_obj
18
+ # * list_my_projects
19
+ #
20
+ module Cli
21
+ ##
22
+ # Generic exception class
23
+ class Error < StandardError; end
24
+
25
+ ##
26
+ # This class provides the complete functionality of the CLI
27
+ #
28
+ class GitlabClient
29
+ # Instance variable to hold an instance of
30
+ # {Jfh::Gitlab::Projects::ListProjects}[rdoc-ref:Jfh::Gitlab::Projects::ListProjects]
31
+ attr_accessor :obj_list_projects
32
+
33
+ def initialize # :nodoc:
34
+ @obj_list_projects = nil
35
+ end
36
+
37
+ # Returns the version string from {Jfh::Gitlab::Cli::VERSION}[rdoc-ref:Jfh::Gitlab::Cli]
38
+ def version
39
+ Jfh::Gitlab::Cli::VERSION
40
+ end
41
+
42
+ # Returns a list of all projects, on +STDOUT+, to which the account is assigned as owner.
43
+ #
44
+ # Determined the Account via +GITLAB_API_PRIVATE_TOKEN+ from the +.env+ file.
45
+ #
46
+ # How many projects are displayed per list side is set via +PAGINATE_PER_PAGE+.
47
+ #
48
+ # The following information is returned per project:
49
+ # * \Gitlab Namespace
50
+ # * Project name
51
+ # * Project ID
52
+ # * Description
53
+ # * \Gitlab SSH uri to the project
54
+ #
55
+ # see also
56
+ # {Jfh::Gitlab::Projects::ListProjects.list_my_projects}[rdoc-ref:Jfh::Gitlab::Projects::ListProjects#list_my_projects]
57
+ #
58
+ # ==== Parameter
59
+ #
60
+ # * +input+ - an object of +IO+, default value is +stdin+
61
+ # * +gitlab_client+ - optionally an object of the class (Gitlab::client)[https://rubygems.org/gems/gitlab]
62
+ #
63
+ def list_my_projects(input: $stdin, gitlab_client: nil)
64
+ @obj_list_projects = Jfh::Gitlab::Projects::ListProjects.new(input:, gitlab_client:) if obj_list_projects.nil?
65
+ obj_list_projects.list_my_projects
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,200 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "colorize"
4
+ require "console_table"
5
+ require "dotenv"
6
+ require "gitlab"
7
+ require "io/console"
8
+ require "wrapomatic"
9
+
10
+ module Jfh
11
+ module Gitlab
12
+ ##
13
+ # This is the Projects modul
14
+ module Projects
15
+ ##
16
+ # Class to list \Gitlab projects
17
+ class ListProjects # rubocop:disable Metrics/ClassLength
18
+ # Holds the obj of {Gitlab::Client}[https://rubygems.org/gitlab]
19
+ attr_accessor :gitlab_client
20
+ # Defines the count of projects per page, default is 5
21
+ attr_accessor :paginate_per_page
22
+ # Defines the configuration of {ConsoleTable}[https://rubygems.org/gems/console_table]
23
+ attr_accessor :table_config
24
+
25
+ # Initialize the object and setup the attributes
26
+ # * {gitlab_client}[rdoc-ref:Jfh::Gitlab::Projects::ListProjects#gitlab_client]
27
+ # * {paginate_perpage}[rdoc-ref:Jfh::Gitlab::Projects::ListProjects#paginate_per_page]
28
+ # * {table_config}[rdoc-ref:Jfh::Gitlab::Projects::ListProjects#table_config]
29
+ #
30
+ # The configuration can be done with a +.env+ file and environment variables
31
+ # GITLAB_API_ENDPOINT=https://gitlab.com/api/v4
32
+ # GITLAB_API_PRIVATE_TOKEN=[your rubygems API key]
33
+ # PAGINATE_PER_PAGE=15
34
+ #
35
+ # === Parameter
36
+ #
37
+ # * +input+ - an object of +IO+, default value is +stdin+
38
+ # * +gitlab_client+ - optionally an object of the class (Gitlab::client)[https://rubygems.org/gems/gitlab]
39
+ #
40
+ # Default of +table_config+:
41
+ # @table_config = [
42
+ # { key: :namespace, size: 40, title: "Namespace" },
43
+ # { key: :project, size: 25, title: "Project" },
44
+ # { key: :project_id, size: 10, title: "Project#", justify: :right },
45
+ # { key: :description, size: 20, title: "Description" },
46
+ # { key: :ssh, size: "*", title: "SSH" },
47
+ # ]
48
+ #
49
+ def initialize(input: $stdin, gitlab_client: nil) # rubocop:disable Metrics/MethodLength
50
+ # :nocov:
51
+ if ENV.fetch("IS_RUNNING_MINITEST", "false") != "true" && !(input.instance_of? IO)
52
+ raise "Expected instance of IO as input parameter"
53
+ end
54
+ # :nocov:
55
+
56
+ @input = input
57
+
58
+ ::Dotenv.load(".env", "~/.jfh-gitlab-cli.env", "/etc/jfh-gitlab-cli.env")
59
+
60
+ init_gitlab_client(gitlab_client)
61
+
62
+ @paginate_per_page = ENV.fetch("PAGINATE_PER_PAGE", "5").to_i if paginate_per_page.nil?
63
+
64
+ return unless table_config.nil?
65
+
66
+ @table_config = [
67
+ { key: :namespace, size: 40, title: "Namespace" },
68
+ { key: :project, size: 25, title: "Project" },
69
+ { key: :project_id, size: 10, title: "Project#", justify: :right },
70
+ { key: :description, size: 20, title: "Description" },
71
+ { key: :ssh, size: "*", title: "SSH" },
72
+ ]
73
+ end
74
+
75
+ # Returns a list of all projects, on +STDOUT+, to which the account is assigned as owner.
76
+ #
77
+ # Determined the Account via +GITLAB_API_PRIVATE_TOKEN+ from the +.env+ file.
78
+ #
79
+ # How many projects are displayed per list side is set via +PAGINATE_PER_PAGE+.
80
+ #
81
+ # The following information is returned per project:
82
+ # * \Gitlab Namespace
83
+ # * Project name
84
+ # * Project ID
85
+ # * Description
86
+ # * \Gitlab SSH uri to the project
87
+ #
88
+ # see also
89
+ # {Jfh::Gitlab::Cli::GitlabClient.list_my_projects}[rdoc-ref:Jfh::Gitlab::Cli::GitlabClient#list_my_projects]
90
+ #
91
+ # ==== Parameter
92
+ #
93
+ # * +input+ - an object of +IO+, default value is +stdin+
94
+ # * +gitlab_client+ - optionally an object of the class (Gitlab::client)[https://rubygems.org/gems/gitlab]
95
+ #
96
+ def list_my_projects
97
+ g = gitlab_client
98
+
99
+ projects = g.projects(per_page: paginate_per_page, owned: true)
100
+
101
+ if projects.has_first_page?
102
+ table_title = "List projects owned by #{g.user.to_h["name"]}"
103
+ paginate_display(projects, table_title)
104
+ else
105
+ puts "No projects owned by #{g.user.to_h["name"]} found.\n\n"
106
+ end
107
+ end
108
+
109
+ private
110
+
111
+ # :nocov:
112
+ def continue_display
113
+ print "press any key or 'q' for quit"
114
+ ch = input.getch
115
+ print " \r"
116
+
117
+ ch == "q" ? "break" : "continue"
118
+ end
119
+ # :nocov:
120
+
121
+ def paginate_display(projects, table_title)
122
+ page = projects.first_page
123
+ loop do
124
+ display_page(page, table_title)
125
+ break if page.has_next_page? == false
126
+
127
+ # FIXME: Test still has to be covered
128
+ # :nocov:
129
+ response = continue_display
130
+ break if response == "break"
131
+
132
+ page = page.next_page
133
+ # :nocov:
134
+ end
135
+ end
136
+
137
+ def display_page(page, table_title)
138
+ formatted_title = table_title.bold.green.underline
139
+ ConsoleTable.define(table_config, left_margin: 5, right_margin: 10, title: formatted_title) do |table|
140
+ page.each do |project|
141
+ get_line(project).each do |line|
142
+ table << line
143
+ end
144
+ end
145
+ end
146
+ end
147
+
148
+ def get_line(project) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
149
+ p = project.to_h
150
+ lines = []
151
+ desc = p["description"].nil? ? "" : p["description"].to_s
152
+ if desc.length > table_config[3][:size]
153
+ wrapped = Wrapomatic.wrap(desc, columns: table_config[3][:size]).split("\n", -1)
154
+ lines << build_row(p, wrapped[0])
155
+ i = 1
156
+ while i < wrapped.length
157
+ lines << build_row(p, wrapped[1], only_desc: true)
158
+ i += 1
159
+ end
160
+
161
+ lines
162
+ else
163
+ lines << build_row(p, desc)
164
+ end
165
+ lines
166
+ end
167
+
168
+ def build_row(p_hash, desc, only_desc: false)
169
+ {
170
+ namespace: only_desc ? "" : p_hash["path_with_namespace"].to_s,
171
+ project: only_desc ? "" : p_hash["name"].to_s.colorize(:yellow),
172
+ project_id: only_desc ? "" : p_hash["id"].to_s.colorize(:green),
173
+ description: desc.colorize(:gray),
174
+ ssh: only_desc ? "" : p_hash["ssh_url_to_repo"].to_s.colorize(:blue),
175
+ }
176
+ end
177
+
178
+ def init_gitlab_client(gitlab_client) # rubocop:disable Metrics/MethodLength
179
+ if gitlab_client.nil?
180
+ @gitlab_client = ::Gitlab.client(
181
+ endpoint: ENV.fetch("GITLAB_API_ENDPOINT", nil),
182
+ private_token: ENV.fetch("GITLAB_API_PRIVATE_TOKEN", nil),
183
+ httparty: {
184
+ options: "{verfiy: false}",
185
+ },
186
+ )
187
+ else
188
+ # :nocov:
189
+ if ENV.fetch("IS_RUNNING_MINITEST", "false") != "true" && !(gitlab_client.instance_of? ::Gitlab::Client)
190
+ raise "Expected instance of Gitlab::Client as gitlab_client parameter"
191
+ end
192
+ # :nocov:
193
+
194
+ @gitlab_client = gitlab_client
195
+ end
196
+ end
197
+ end
198
+ end
199
+ end
200
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ # :nocov:
4
+ namespace :release do
5
+ gemspec = Bundler.load_gemspec(Dir.glob("*.gemspec").first)
6
+ package = "#{gemspec.name}-#{gemspec.version}.gem"
7
+
8
+ desc "Display the gemfile name: #{package}"
9
+ task :gemfile do
10
+ puts package
11
+ end
12
+ end
13
+ # :nocov:
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rubygems/commands/push_command"
4
+
5
+ # :nocov:
6
+ namespace :release do
7
+ gemspec = Bundler.load_gemspec(Dir.glob("*.gemspec").first)
8
+ package = "#{gemspec.name}-#{gemspec.version}.gem"
9
+ package_fullpath = "pkg/#{package}"
10
+
11
+ desc "Build and push #{package} to rubygems.org, CREATES NO TAG!"
12
+ task :push do
13
+ Rake::Task["build"].execute
14
+ Rake::Task["build:checksum"].execute
15
+
16
+ cmd = Gem::Commands::PushCommand.new
17
+ cmd.invoke package_fullpath
18
+ end
19
+ end
20
+ # :nocov: