qb 0.3.8 → 0.3.9
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 +4 -4
- data/.yardopts +4 -0
- data/exe/.qb_interop_receive +39 -0
- data/exe/qb +8 -5
- data/lib/qb.rb +64 -19
- data/lib/qb/cli/run.rb +1 -1
- data/lib/qb/github.rb +4 -0
- data/lib/qb/github/api.rb +43 -0
- data/lib/qb/github/issue.rb +83 -0
- data/lib/qb/github/repo_id.rb +127 -0
- data/lib/qb/github/resource.rb +59 -0
- data/lib/qb/github/types.rb +45 -0
- data/lib/qb/package.rb +131 -0
- data/lib/qb/package/gem.rb +2 -4
- data/lib/qb/package/version.rb +175 -2
- data/lib/qb/path.rb +2 -2
- data/lib/qb/repo.rb +137 -1
- data/lib/qb/repo/git.rb +55 -23
- data/lib/qb/repo/git/github.rb +137 -0
- data/lib/qb/role.rb +74 -30
- data/lib/qb/util.rb +1 -4
- data/lib/qb/util/docker_mixin.rb +30 -2
- data/lib/qb/util/interop.rb +68 -7
- data/lib/qb/util/logging.rb +215 -0
- data/lib/qb/util/stdio.rb +25 -9
- data/lib/qb/version.rb +16 -28
- data/library/stream +2 -2
- data/plugins/filter_plugins/ruby_interop_plugins.py +49 -31
- data/qb.gemspec +16 -4
- data/roles/qb.role/defaults/main.yml +6 -2
- data/roles/{qb.bump → qb/pkg/bump}/.qb-options.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/README.md +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/defaults/main.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/library/bump +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/meta/main.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/meta/qb.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/tasks/frontend/level/dev.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/tasks/frontend/level/rc.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/tasks/frontend/level/release.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/tasks/frontend/main.yml +0 -0
- data/roles/{qb.bump → qb/pkg/bump}/tasks/main.yml +1 -1
- data/roles/{qb.qb_role → qb/role/qb}/.qb-options.yml +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/defaults/main.yml +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/meta/main.yml +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/meta/qb.yml +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/tasks/main.yml +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/templates/.gitkeep +0 -0
- data/roles/{qb.qb_role → qb/role/qb}/templates/qb.yml.j2 +0 -0
- data/roles/qb/test/rspec/spec/issue/defaults/main.yml +2 -0
- data/roles/qb/test/rspec/spec/issue/meta/main.yml +8 -0
- data/roles/qb/test/rspec/spec/issue/meta/qb.yml +67 -0
- data/roles/qb/test/rspec/spec/issue/tasks/main.yml +21 -0
- metadata +95 -26
@@ -0,0 +1,59 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =======================================================================
|
3
|
+
|
4
|
+
# Stdlib
|
5
|
+
# -----------------------------------------------------------------------
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Project / Package
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
|
14
|
+
# Refinements
|
15
|
+
# =======================================================================
|
16
|
+
|
17
|
+
|
18
|
+
# Declarations
|
19
|
+
# =======================================================================
|
20
|
+
|
21
|
+
|
22
|
+
# Definitions
|
23
|
+
# =======================================================================
|
24
|
+
|
25
|
+
|
26
|
+
# @todo document QB::GitHub::Resource class.
|
27
|
+
class QB::GitHub::Resource < QB::Util::Resource
|
28
|
+
|
29
|
+
# Constants
|
30
|
+
# ======================================================================
|
31
|
+
|
32
|
+
|
33
|
+
# Class Methods
|
34
|
+
# ======================================================================
|
35
|
+
|
36
|
+
|
37
|
+
# Attributes
|
38
|
+
# ======================================================================
|
39
|
+
|
40
|
+
|
41
|
+
# Constructor
|
42
|
+
# ======================================================================
|
43
|
+
|
44
|
+
# Instantiate a new `QB::GitHub::Resource`.
|
45
|
+
def initialize octokit_resource
|
46
|
+
@octokit_resource = octokit_resource
|
47
|
+
end # #initialize
|
48
|
+
|
49
|
+
|
50
|
+
# Instance Methods
|
51
|
+
# ======================================================================
|
52
|
+
|
53
|
+
|
54
|
+
end # class QB::GitHub::Resource
|
55
|
+
|
56
|
+
|
57
|
+
|
58
|
+
# Post-Processing
|
59
|
+
# =======================================================================
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Requirements
|
2
|
+
# =======================================================================
|
3
|
+
|
4
|
+
# Stdlib
|
5
|
+
# -----------------------------------------------------------------------
|
6
|
+
|
7
|
+
# Deps
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Project / Package
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
|
14
|
+
# Refinements
|
15
|
+
# =======================================================================
|
16
|
+
|
17
|
+
require 'nrser/refinements'
|
18
|
+
using NRSER
|
19
|
+
|
20
|
+
require 'nrser/refinements/types'
|
21
|
+
using NRSER::Types
|
22
|
+
|
23
|
+
|
24
|
+
# Declarations
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
module QB; end
|
28
|
+
module QB::GitHub; end
|
29
|
+
|
30
|
+
|
31
|
+
# Definitions
|
32
|
+
# =======================================================================
|
33
|
+
|
34
|
+
module QB::GitHub::Types
|
35
|
+
|
36
|
+
def self.repo_name
|
37
|
+
t.path_seg name: 'GitHubRepoName(String)'
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.repo_owner
|
41
|
+
t.path_seg name: 'GitHubRepoOwner(String)'
|
42
|
+
end
|
43
|
+
|
44
|
+
end # module QB::GitHub::Types
|
45
|
+
|
data/lib/qb/package.rb
CHANGED
@@ -92,6 +92,137 @@ class QB::Package < QB::Util::Resource
|
|
92
92
|
prop :name, type: t.non_empty_str
|
93
93
|
|
94
94
|
|
95
|
+
# @!attribute [r] repo_rel_path
|
96
|
+
# @todo Doc repo_rel_path property...
|
97
|
+
#
|
98
|
+
# @return [PropRubyType]
|
99
|
+
#
|
100
|
+
prop :repo_rel_path,
|
101
|
+
type: t.maybe( t.dir_path ),
|
102
|
+
source: :repo_rel_path
|
103
|
+
|
104
|
+
|
105
|
+
# Constructor
|
106
|
+
# =====================================================================
|
107
|
+
|
108
|
+
def initialize repo: NRSER::NO_ARG, **props
|
109
|
+
@repo = repo
|
110
|
+
super **props
|
111
|
+
end # #initialize
|
112
|
+
|
113
|
+
|
114
|
+
# Instance Methods
|
115
|
+
# =====================================================================
|
116
|
+
|
117
|
+
# Repository
|
118
|
+
# ---------------------------------------------------------------------
|
119
|
+
|
120
|
+
# @todo Document repo method.
|
121
|
+
#
|
122
|
+
# @param [type] arg_name
|
123
|
+
# @todo Add name param description.
|
124
|
+
#
|
125
|
+
# @return [return_type]
|
126
|
+
# @todo Document return value.
|
127
|
+
#
|
128
|
+
def repo
|
129
|
+
if @repo == NRSER::NO_ARG
|
130
|
+
@repo = QB::Repo.from_path root_path
|
131
|
+
end
|
132
|
+
|
133
|
+
@repo
|
134
|
+
end # #repo
|
135
|
+
|
136
|
+
|
137
|
+
# @return [Boolean]
|
138
|
+
# `true` if {#root_path} is in a repo type we recognize.
|
139
|
+
#
|
140
|
+
def in_repo?
|
141
|
+
!!repo
|
142
|
+
end # #in_repo?
|
143
|
+
|
144
|
+
|
145
|
+
# Relative path from the {#repo} root to the {#root_path}.
|
146
|
+
#
|
147
|
+
# Used as the version tag prefix (unless it's `.` - when the repo root is
|
148
|
+
# the root path).
|
149
|
+
#
|
150
|
+
# @return [Pathname]
|
151
|
+
#
|
152
|
+
def repo_rel_path
|
153
|
+
root_path.relative_path_from( repo.root_path ) if in_repo?
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
# Get the string prefix for tagging versions of this package.
|
158
|
+
#
|
159
|
+
# Only makes any sense if the package is in a recognized repo, and will error
|
160
|
+
# out if that's not the case.
|
161
|
+
#
|
162
|
+
# The most basic prefix is "v" for packages located at the root of the
|
163
|
+
# repository.
|
164
|
+
#
|
165
|
+
# @example
|
166
|
+
# repo_root = '.'
|
167
|
+
# package_root = repo_root
|
168
|
+
# QB::Package.from_path( package_root ).version_tag_prefix
|
169
|
+
# # => 'v'
|
170
|
+
# # (an actual tag would look like 'v0.1.2')
|
171
|
+
#
|
172
|
+
# To support "multi-package" repos - which is a way of dealing with apps that
|
173
|
+
# are composed of multiple versioned services without having to create a new
|
174
|
+
# submodule for every micro-service - packages that do not share the same
|
175
|
+
# root of the repo are prefixed by the relative path from the repo root to
|
176
|
+
# the package root.
|
177
|
+
#
|
178
|
+
# @example
|
179
|
+
# repo_root = Pathname.new '.'
|
180
|
+
# package_root = repo_root / 'services' / 'some-service'
|
181
|
+
# QB::Package.from_path( package_root ).version_tag_prefix
|
182
|
+
# # => 'services/some-service/v'
|
183
|
+
# # (an actual tag would look like 'services/some-service/v0.1.2')
|
184
|
+
#
|
185
|
+
# This creates a unique and intuitive namespace scheme for supporting
|
186
|
+
# multiple independent package versions in a single repo, which has proved
|
187
|
+
# handy for container-ized apps.
|
188
|
+
#
|
189
|
+
# Unless, of course, you change the package's path. Then it will get wonky.
|
190
|
+
# We'll burn that bridge when we come to it.
|
191
|
+
#
|
192
|
+
# @return [String]
|
193
|
+
#
|
194
|
+
def version_tag_prefix
|
195
|
+
if root_path == repo.root_path
|
196
|
+
'v'
|
197
|
+
else
|
198
|
+
(repo_rel_path / 'v').to_s
|
199
|
+
end
|
200
|
+
end # #version_tag_prefix
|
201
|
+
|
202
|
+
|
203
|
+
|
204
|
+
#
|
205
|
+
#
|
206
|
+
# @return [String]
|
207
|
+
#
|
208
|
+
def version_tag
|
209
|
+
version_tag_prefix + version.semver
|
210
|
+
end # #version_tag
|
211
|
+
|
212
|
+
|
213
|
+
# @todo Document versions method.
|
214
|
+
#
|
215
|
+
# @param [type] arg_name
|
216
|
+
# @todo Add name param description.
|
217
|
+
#
|
218
|
+
# @return [return_type]
|
219
|
+
# @todo Document return value.
|
220
|
+
#
|
221
|
+
def versions
|
222
|
+
# method body...
|
223
|
+
end # #versions
|
224
|
+
|
225
|
+
|
95
226
|
end # class QB::Package
|
96
227
|
|
97
228
|
|
data/lib/qb/package/gem.rb
CHANGED
@@ -71,9 +71,9 @@ class QB::Package::Gem < QB::Package
|
|
71
71
|
# @raise [QB::FSStateError]
|
72
72
|
# If `path` is not a directory.
|
73
73
|
#
|
74
|
-
def from_root_path path
|
74
|
+
def from_root_path path, repo: NRSER::NO_ARG
|
75
75
|
# Values we will use to construct the resource instance.
|
76
|
-
values = {}
|
76
|
+
values = {repo: repo}
|
77
77
|
|
78
78
|
# Whatever we were passes is the reference path
|
79
79
|
values[:ref_path] = path
|
@@ -129,8 +129,6 @@ class QB::Package::Gem < QB::Package
|
|
129
129
|
}
|
130
130
|
end # #from_root_path!
|
131
131
|
|
132
|
-
|
133
|
-
|
134
132
|
end # class << self (Eigenclass)
|
135
133
|
|
136
134
|
|
data/lib/qb/package/version.rb
CHANGED
@@ -17,6 +17,9 @@ require 'qb/util/resource'
|
|
17
17
|
# Refinements
|
18
18
|
# =======================================================================
|
19
19
|
|
20
|
+
require 'nrser/refinements'
|
21
|
+
using NRSER
|
22
|
+
|
20
23
|
require 'nrser/refinements/types'
|
21
24
|
using NRSER::Types
|
22
25
|
|
@@ -41,6 +44,7 @@ class QB::Package::Version < QB::Util::Resource
|
|
41
44
|
# Mixins
|
42
45
|
# =====================================================================
|
43
46
|
|
47
|
+
include Comparable
|
44
48
|
include QB::Util::DockerMixin
|
45
49
|
|
46
50
|
|
@@ -52,6 +56,36 @@ class QB::Package::Version < QB::Util::Resource
|
|
52
56
|
MIXED_SEGMENT = t.union NUMBER_SEGMENT, NAME_SEGMENT
|
53
57
|
|
54
58
|
|
59
|
+
# Reasonably simple regular expression to extract things that might be
|
60
|
+
# versions from strings.
|
61
|
+
#
|
62
|
+
# Intended for use on reasonably short strings like `git tag` output or
|
63
|
+
# what-not... probably not well suited for sifting through mountains of
|
64
|
+
# text.
|
65
|
+
#
|
66
|
+
# Structure:
|
67
|
+
#
|
68
|
+
# 1. The major version number, matched by a digit `1-9` followed by any
|
69
|
+
# number of digits.
|
70
|
+
# 2. A separator to the next segment, which is:
|
71
|
+
# 1. `.` separating to the minor version number
|
72
|
+
# 2. `-` separating to the prerelease
|
73
|
+
# 3. `+` separating to the build
|
74
|
+
# 3. One or more of `a-z`, `A-Z`, `0-9`, `.`, `-`, `_`, `+`
|
75
|
+
# 4. Ends with one of those that is *not* `.`, `_` or `+`, so `a-z`, `A-Z`,
|
76
|
+
# `0-9`.
|
77
|
+
#
|
78
|
+
# This will match *many* strings that are not versions, but it should not
|
79
|
+
# miss any that are. It cold obviously be refined and improve to reduce
|
80
|
+
# false positives at the cost of additional complexity, but I wanted to
|
81
|
+
# start simple and complicate it as needed.
|
82
|
+
#
|
83
|
+
# @return [Regexp]
|
84
|
+
#
|
85
|
+
POSSIBLE_VERSION_RE = \
|
86
|
+
/(?:0|[1-9]\d*)[\.\-\+][a-zA-Z0-9\.\-\_\+]*[a-zA-Z0-9\-]+/
|
87
|
+
|
88
|
+
|
55
89
|
# Props
|
56
90
|
# =====================================================================
|
57
91
|
|
@@ -89,9 +123,13 @@ class QB::Package::Version < QB::Util::Resource
|
|
89
123
|
# Utilities
|
90
124
|
# ---------------------------------------------------------------------
|
91
125
|
|
126
|
+
# Time formatted to be stuck in a version segment per [Semver][] spec.
|
127
|
+
# We also strip out '-' to avoid possible parsing weirdness.
|
128
|
+
#
|
129
|
+
# [Semver]: https://semver.org/
|
130
|
+
#
|
92
131
|
# @return [String]
|
93
|
-
#
|
94
|
-
# We also strip out '-' to avoid possible parsing weirdness.
|
132
|
+
#
|
95
133
|
def self.to_time_segment time
|
96
134
|
time.utc.iso8601.gsub /[^0-9A-Za-z]/, ''
|
97
135
|
end
|
@@ -131,6 +169,7 @@ class QB::Package::Version < QB::Util::Resource
|
|
131
169
|
build: []
|
132
170
|
end
|
133
171
|
|
172
|
+
|
134
173
|
def self.from_npm_version version
|
135
174
|
stmt = NRSER.squish <<-END
|
136
175
|
var Semver = require('semver');
|
@@ -186,6 +225,27 @@ class QB::Package::Version < QB::Util::Resource
|
|
186
225
|
end
|
187
226
|
end
|
188
227
|
|
228
|
+
singleton_class.send :alias_method, :from_s, :from_string
|
229
|
+
|
230
|
+
|
231
|
+
# Extract version number from a string.
|
232
|
+
#
|
233
|
+
# @param [String] string
|
234
|
+
# String containing versions.
|
235
|
+
#
|
236
|
+
# @return [Array<QB::Package::Version]
|
237
|
+
# Any versions extracted from the string.
|
238
|
+
#
|
239
|
+
def self.extract string
|
240
|
+
string.scan( POSSIBLE_VERSION_RE ).map { |possible_version_string|
|
241
|
+
begin
|
242
|
+
from_string possible_version_string
|
243
|
+
rescue
|
244
|
+
nil
|
245
|
+
end
|
246
|
+
}.compact
|
247
|
+
end # .extract
|
248
|
+
|
189
249
|
|
190
250
|
# Constructor
|
191
251
|
# =====================================================================
|
@@ -388,6 +448,114 @@ class QB::Package::Version < QB::Util::Resource
|
|
388
448
|
end # #prerelease_version
|
389
449
|
|
390
450
|
|
451
|
+
# Bumping
|
452
|
+
# ---------------------------------------------------------------------
|
453
|
+
|
454
|
+
|
455
|
+
# @todo Document bump_dev method.
|
456
|
+
#
|
457
|
+
# @param [type] arg_name
|
458
|
+
# @todo Add name param description.
|
459
|
+
#
|
460
|
+
# @return [return_type]
|
461
|
+
# @todo Document return value.
|
462
|
+
#
|
463
|
+
def bump_to_dev
|
464
|
+
props = { prerelease: ['dev'] }
|
465
|
+
|
466
|
+
case self.level
|
467
|
+
when 'release'
|
468
|
+
merge patch: patch.succ, **props
|
469
|
+
when 'rc'
|
470
|
+
merge **props
|
471
|
+
when 'dev'
|
472
|
+
self
|
473
|
+
end
|
474
|
+
end # #bump_dev
|
475
|
+
|
476
|
+
|
477
|
+
# Bump to next release-candidate version.
|
478
|
+
#
|
479
|
+
# This is a little tricky because we need to know what the *last* rc
|
480
|
+
# version was, which is not in the version in most cases.
|
481
|
+
#
|
482
|
+
# @param [type] arg_name
|
483
|
+
# @todo Add name param description.
|
484
|
+
#
|
485
|
+
# @return [return_type]
|
486
|
+
# @todo Document return value.
|
487
|
+
#
|
488
|
+
def bump_to_rc existing_versions: nil
|
489
|
+
case self.level
|
490
|
+
when 'release'
|
491
|
+
merge patch: patch.succ, prerelease: ['rc', 0]
|
492
|
+
when 'rc'
|
493
|
+
merge prerelease: ['rc', prerelease[1].succ]
|
494
|
+
when 'dev'
|
495
|
+
if existing_versions.nil?
|
496
|
+
raise ArgumentError.squished <<-END
|
497
|
+
Can't bump to next rc version without knowing what rc versions have
|
498
|
+
already been used.
|
499
|
+
END
|
500
|
+
elsif existing_versions.is_a? String
|
501
|
+
existing_versions = self.class.extract existing_versions
|
502
|
+
end
|
503
|
+
|
504
|
+
last_existing_rc = existing_versions.
|
505
|
+
select { |version|
|
506
|
+
version.rc? && version.release == release
|
507
|
+
}.
|
508
|
+
sort.
|
509
|
+
last
|
510
|
+
|
511
|
+
rc_number = if last_existing_rc.nil?
|
512
|
+
0
|
513
|
+
else
|
514
|
+
last_existing_rc.prerelease[1].succ
|
515
|
+
end
|
516
|
+
|
517
|
+
merge prerelease: ['rc', rc_number]
|
518
|
+
end
|
519
|
+
end # #bump_rc
|
520
|
+
|
521
|
+
|
522
|
+
# @todo Document bump_to_release method.
|
523
|
+
#
|
524
|
+
# @param [type] arg_name
|
525
|
+
# @todo Add name param description.
|
526
|
+
#
|
527
|
+
# @return [return_type]
|
528
|
+
# @todo Document return value.
|
529
|
+
#
|
530
|
+
def bump_to_release
|
531
|
+
case self.level
|
532
|
+
when 'release'
|
533
|
+
# bump forward to next release, M.m.p -> M.m.(p+1)
|
534
|
+
merge patch: patch.succ
|
535
|
+
when 'rc', 'dev'
|
536
|
+
# bump forward to release version for rc or dev
|
537
|
+
release
|
538
|
+
end
|
539
|
+
end # #bump_to_release
|
540
|
+
|
541
|
+
|
542
|
+
# @todo Document bump method.
|
543
|
+
#
|
544
|
+
# @param [type] arg_name
|
545
|
+
# @todo Add name param description.
|
546
|
+
#
|
547
|
+
# @return [return_type]
|
548
|
+
# @todo Document return value.
|
549
|
+
#
|
550
|
+
def bump level:, **options
|
551
|
+
method_name = "bump_to_#{ level }"
|
552
|
+
if options.empty?
|
553
|
+
public_send method_name
|
554
|
+
else
|
555
|
+
public_send method_name, **options
|
556
|
+
end
|
557
|
+
end # #bump
|
558
|
+
|
391
559
|
|
392
560
|
# Language Interface
|
393
561
|
# =====================================================================
|
@@ -408,6 +576,11 @@ class QB::Package::Version < QB::Util::Resource
|
|
408
576
|
end # #==
|
409
577
|
|
410
578
|
|
579
|
+
def <=> other
|
580
|
+
to_a <=> other.to_a
|
581
|
+
end
|
582
|
+
|
583
|
+
|
411
584
|
# Return array of the version elements in order from greatest to least
|
412
585
|
# precedence.
|
413
586
|
#
|