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

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