monofile 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +4 -0
- data/lib/monofile.rb +11 -234
- data/lib/monofile/monofile.rb +226 -0
- data/lib/monofile/mononame.rb +132 -0
- data/lib/monofile/version.rb +2 -2
- data/test/helper.rb +7 -0
- data/test/test_names.rb +96 -0
- metadata +5 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b40761cdf41323e67c0f31dc5322ae1d33a73a40
|
4
|
+
data.tar.gz: 69eebef7b4e3a036eaf45c2888fdaaaaae0b0dc8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b35816490aff623a84368d646fdb68ba9c999009210a613c6731f1636b0b00a7d23e6d5a99e9041700c067f4d929b54d1b780fa6081512d99b297a40c9db73f8
|
7
|
+
data.tar.gz: dd939bbab36398a63340e2810f86774a077676f0bad3a91bee3220a9ecceb7f6a7828df64f2da41b5369249117424b5857d37a774da46aaecb2e9d6c18a3fa22
|
data/Manifest.txt
CHANGED
data/lib/monofile.rb
CHANGED
@@ -20,6 +20,8 @@ require 'optparse'
|
|
20
20
|
#####################
|
21
21
|
# our own code
|
22
22
|
require 'monofile/version' # note: let version always go first
|
23
|
+
require 'monofile/mononame'
|
24
|
+
require 'monofile/monofile'
|
23
25
|
|
24
26
|
|
25
27
|
|
@@ -64,240 +66,11 @@ end ## module Mono
|
|
64
66
|
|
65
67
|
|
66
68
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
## nested class
|
73
|
-
class Project
|
74
|
-
|
75
|
-
## use some different names / attributes ??
|
76
|
-
attr_reader :org, ## todo/check: find a different name (or add alias e.g. login/user/etc.)
|
77
|
-
:name
|
78
|
-
|
79
|
-
## todo/fix:
|
80
|
-
## - use *args and than split if args==2 or args==1 etc.
|
81
|
-
def initialize( *args )
|
82
|
-
if args.size == 2 && args[0].is_a?(String) && args[1].is_a?(String)
|
83
|
-
## assume [org, name]
|
84
|
-
@org = args[0]
|
85
|
-
@name = args[1]
|
86
|
-
elsif args.size == 1 && args[0].is_a?( String )
|
87
|
-
## todo/fix: use norm_name parser or such!!!!
|
88
|
-
parts = args[0].split( '/' )
|
89
|
-
@org = parts[0][1..-1] ## cut-off leading @ (always assume for now!!)
|
90
|
-
@name = parts[1]
|
91
|
-
else
|
92
|
-
raise ArgumentError, "[Monorepo::Project] one or two string args expected; got: #{args.pretty_inspect}"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
def to_s() "@#{org}/#{name}"; end
|
97
|
-
def to_path() "#{org}/#{name}"; end
|
98
|
-
|
99
|
-
## add clone_ssh_url or such too!!!!
|
100
|
-
end ## (nested) class Project
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
class Builder ## "clean room" pattern/spell - keep accessible methods to a minimum (by eval in "cleanroom")
|
105
|
-
def initialize( monofile )
|
106
|
-
@monofile = monofile
|
107
|
-
end
|
108
|
-
|
109
|
-
def project( *args )
|
110
|
-
project = Project.new( *args )
|
111
|
-
@monofile.projects << project
|
112
|
-
end
|
113
|
-
end # (nested) class Builder
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
RUBY_NAMES = ['monofile',
|
118
|
-
'Monofile',
|
119
|
-
'monofile.rb',
|
120
|
-
'Monofile.rb',
|
121
|
-
]
|
122
|
-
|
123
|
-
TXT_NAMES = ['monofile.txt',
|
124
|
-
'monotree.txt', ## keep monotree - why? why not?
|
125
|
-
'monorepo.txt',
|
126
|
-
'repos.txt']
|
127
|
-
|
128
|
-
## note: yaml always requires an extension
|
129
|
-
YML_NAMES = ['monofile.yml', 'monofile.yaml',
|
130
|
-
'monotree.yml', 'monotree.yaml', ## keep monotree - why? why not?
|
131
|
-
'monorepo.yml', 'monorepo.yaml',
|
132
|
-
'repos.yml', 'repos.yaml',
|
133
|
-
] ## todo/check: add mono.yml too - why? why not?
|
134
|
-
|
135
|
-
NAMES = RUBY_NAMES + TXT_NAMES + YML_NAMES
|
136
|
-
|
137
|
-
|
138
|
-
def self.find
|
139
|
-
RUBY_NAMES.each do |name|
|
140
|
-
return "./#{name}" if File.exist?( "./#{name}")
|
141
|
-
end
|
142
|
-
|
143
|
-
TXT_NAMES.each do |name|
|
144
|
-
return "./#{name}" if File.exist?( "./#{name}")
|
145
|
-
end
|
146
|
-
|
147
|
-
YML_NAMES.each do |name|
|
148
|
-
return "./#{name}" if File.exist?( "./#{name}")
|
149
|
-
end
|
150
|
-
|
151
|
-
nil ## no monofile found; return nil
|
152
|
-
end
|
153
|
-
|
154
|
-
|
155
|
-
def self.read( path )
|
156
|
-
txt = File.open( path, 'r:utf-8') { |f| f.read }
|
157
|
-
|
158
|
-
## check for yml or yaml extension;
|
159
|
-
## or for txt extension; otherwise assume ruby
|
160
|
-
extname = File.extname( path ).downcase
|
161
|
-
if ['.yml', '.yaml'].include?( extname )
|
162
|
-
hash = YAML.load( txt )
|
163
|
-
new( hash )
|
164
|
-
elsif ['.txt'].include?( extname )
|
165
|
-
new( txt )
|
166
|
-
else ## assume ruby code (as text in string)
|
167
|
-
new().load( txt )
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
def self.load( code )
|
174
|
-
monofile = new
|
175
|
-
monofile.load( code )
|
176
|
-
monofile
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.load_file( path ) ## keep (or add load_yaml to or such) - why? why not?
|
180
|
-
code = File.open( path, 'r:utf-8') { |f| f.read }
|
181
|
-
load( code )
|
182
|
-
end
|
183
|
-
|
184
|
-
|
185
|
-
### attr readers
|
186
|
-
def projects() @projects; end
|
187
|
-
def size() @projects.size; end
|
188
|
-
|
189
|
-
|
190
|
-
def initialize( obj={} ) ## todo/fix: change default to obj=[]
|
191
|
-
@projects = []
|
192
|
-
|
193
|
-
## puts "[debug] obj.class=#{obj.class.name}"
|
194
|
-
add( obj )
|
195
|
-
end
|
196
|
-
|
197
|
-
def load( code ) ## note: code is text as a string
|
198
|
-
builder = Builder.new( self )
|
199
|
-
builder.instance_eval( code )
|
200
|
-
self ## note: for chaining always return self
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
def add( obj )
|
205
|
-
## todo/check: check for proc too! and use load( proc/block ) - possible?
|
206
|
-
if obj.is_a?( String )
|
207
|
-
puts "sorry add String - to be done!!!"
|
208
|
-
exit 1
|
209
|
-
elsif obj.is_a?( Array )
|
210
|
-
puts "sorry add Array- to be done!!!"
|
211
|
-
exit 1
|
212
|
-
elsif obj.is_a?( Hash )
|
213
|
-
add_hash( obj )
|
214
|
-
else ## assume text (evaluate/parse)
|
215
|
-
puts "sorry add Text - to be done!!!"
|
216
|
-
exit 1
|
217
|
-
end
|
218
|
-
self ## note: return self for chaining
|
219
|
-
end
|
220
|
-
|
221
|
-
|
222
|
-
def add_hash( hash )
|
223
|
-
hash.each do |org_with_counter, names|
|
224
|
-
|
225
|
-
## remove optional number from key e.g.
|
226
|
-
## mrhydescripts (3) => mrhydescripts
|
227
|
-
## footballjs (4) => footballjs
|
228
|
-
## etc.
|
229
|
-
|
230
|
-
## todo/check: warn about duplicates or such - why? why not?
|
231
|
-
|
232
|
-
org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip.to_s
|
233
|
-
|
234
|
-
names.each do |name|
|
235
|
-
@projects << Project.new( org, name )
|
236
|
-
end
|
237
|
-
end
|
238
|
-
|
239
|
-
self ## note: return self for chaining
|
240
|
-
end
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
def each( &block )
|
245
|
-
## puts "[debug] arity: #{block.arity}"
|
246
|
-
|
247
|
-
## for backwards compatibility support "old" each with/by org & names
|
248
|
-
## add deprecated warnings and use to_h or such - why? why not?
|
249
|
-
if block.arity == 2
|
250
|
-
puts "!! DEPRECATED - please, use Monofile#to_h or Monofile.each {|proj| ...}"
|
251
|
-
to_h.each do |org, names|
|
252
|
-
block.call( org, names )
|
253
|
-
end
|
254
|
-
else
|
255
|
-
## assume just regular
|
256
|
-
@projects.each do |project|
|
257
|
-
block.call( project )
|
258
|
-
end
|
259
|
-
end
|
260
|
-
end # method each
|
261
|
-
|
262
|
-
def each_with_index( &block )
|
263
|
-
@projects.each_with_index do |project,i|
|
264
|
-
block.call( project, i )
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
### for backward compat(ibility) add a hash in the form e.g:
|
271
|
-
##
|
272
|
-
## geraldb:
|
273
|
-
## - austria
|
274
|
-
## - catalog
|
275
|
-
## - geraldb.github.io
|
276
|
-
## - logos
|
277
|
-
## yorobot:
|
278
|
-
## - auto
|
279
|
-
## - backup
|
280
|
-
## - football.json
|
281
|
-
## - logs
|
282
|
-
##
|
283
|
-
def to_h
|
284
|
-
h = {}
|
285
|
-
@projects.each do |project|
|
286
|
-
h[ project.org ] ||= []
|
287
|
-
h[ project.org ] << project.name
|
288
|
-
end
|
289
|
-
h
|
290
|
-
end
|
291
|
-
|
292
|
-
def to_a
|
293
|
-
## todo/check:
|
294
|
-
## - sort all entries a-z - why? why not?
|
295
|
-
## - always start name with @ marker - why? why not?
|
296
|
-
@projects.map {|project| project.to_s }
|
297
|
-
end
|
298
|
-
end # class Monofile
|
299
|
-
|
300
|
-
|
69
|
+
###
|
70
|
+
## add some convenience alias for alternate spelling (CamelCase)
|
71
|
+
MonoName = Mononame
|
72
|
+
MonoPath = Monopath
|
73
|
+
MonoFile = Monofile
|
301
74
|
|
302
75
|
|
303
76
|
|
@@ -305,6 +78,9 @@ class Monofile
|
|
305
78
|
class Tool
|
306
79
|
def self.main( args=ARGV )
|
307
80
|
|
81
|
+
## todo/fix:
|
82
|
+
## check args - if any, use/read monofiles in args!!!
|
83
|
+
|
308
84
|
path = Monofile.find
|
309
85
|
if path.nil?
|
310
86
|
puts "!! ERROR: no mono configuration file found; looking for #{Monofile::NAMES.join(', ')} in (#{Dir.getwd})"
|
@@ -332,5 +108,6 @@ end # (nested) class Tool
|
|
332
108
|
end # class Monofile
|
333
109
|
|
334
110
|
|
111
|
+
|
335
112
|
Mono::Module::Monofile.banner
|
336
113
|
|
@@ -0,0 +1,226 @@
|
|
1
|
+
|
2
|
+
class Monofile
|
3
|
+
## holds a list of projects
|
4
|
+
|
5
|
+
## nested class
|
6
|
+
class Project ## todo/fix: change to Monoproject/MonoProject - why? why not?
|
7
|
+
def initialize( *args )
|
8
|
+
if args.size == 2 && args[0].is_a?(String) && args[1].is_a?(String)
|
9
|
+
## assume [org, name]
|
10
|
+
@name = Mononame.new( *args )
|
11
|
+
elsif args.size == 1 && args[0].is_a?( String )
|
12
|
+
@name = Mononame.parse( args[0] )
|
13
|
+
else
|
14
|
+
raise ArgumentError, "[MonoProject] one or two string args expected; got: #{args.pretty_inspect}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def org() @name.org; end
|
19
|
+
def name() @name.name; end
|
20
|
+
|
21
|
+
def to_path() @name.to_path; end
|
22
|
+
def to_s() @name.to_s; end
|
23
|
+
|
24
|
+
## add clone_ssh_url or such too!!!!
|
25
|
+
end ## (nested) class Project
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
class Builder ## "clean room" pattern/spell - keep accessible methods to a minimum (by eval in "cleanroom")
|
30
|
+
def initialize( monofile )
|
31
|
+
@monofile = monofile
|
32
|
+
end
|
33
|
+
|
34
|
+
def project( *args )
|
35
|
+
project = Project.new( *args )
|
36
|
+
@monofile.projects << project
|
37
|
+
end
|
38
|
+
end # (nested) class Builder
|
39
|
+
|
40
|
+
|
41
|
+
|
42
|
+
RUBY_NAMES = ['monofile',
|
43
|
+
'Monofile',
|
44
|
+
'monofile.rb',
|
45
|
+
'Monofile.rb',
|
46
|
+
]
|
47
|
+
|
48
|
+
TXT_NAMES = ['monofile.txt',
|
49
|
+
'monotree.txt', ## keep monotree - why? why not?
|
50
|
+
'monorepo.txt',
|
51
|
+
'repos.txt']
|
52
|
+
|
53
|
+
## note: yaml always requires an extension
|
54
|
+
YML_NAMES = ['monofile.yml', 'monofile.yaml',
|
55
|
+
'monotree.yml', 'monotree.yaml', ## keep monotree - why? why not?
|
56
|
+
'monorepo.yml', 'monorepo.yaml',
|
57
|
+
'repos.yml', 'repos.yaml',
|
58
|
+
] ## todo/check: add mono.yml too - why? why not?
|
59
|
+
|
60
|
+
NAMES = RUBY_NAMES + TXT_NAMES + YML_NAMES
|
61
|
+
|
62
|
+
|
63
|
+
def self.find
|
64
|
+
RUBY_NAMES.each do |name|
|
65
|
+
return "./#{name}" if File.exist?( "./#{name}")
|
66
|
+
end
|
67
|
+
|
68
|
+
TXT_NAMES.each do |name|
|
69
|
+
return "./#{name}" if File.exist?( "./#{name}")
|
70
|
+
end
|
71
|
+
|
72
|
+
YML_NAMES.each do |name|
|
73
|
+
return "./#{name}" if File.exist?( "./#{name}")
|
74
|
+
end
|
75
|
+
|
76
|
+
nil ## no monofile found; return nil
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
def self.read( path )
|
81
|
+
txt = File.open( path, 'r:utf-8') { |f| f.read }
|
82
|
+
|
83
|
+
## check for yml or yaml extension;
|
84
|
+
## or for txt extension; otherwise assume ruby
|
85
|
+
extname = File.extname( path ).downcase
|
86
|
+
if ['.yml', '.yaml'].include?( extname )
|
87
|
+
hash = YAML.load( txt )
|
88
|
+
new( hash )
|
89
|
+
elsif ['.txt'].include?( extname )
|
90
|
+
new( txt )
|
91
|
+
else ## assume ruby code (as text in string)
|
92
|
+
new().load( txt )
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
def self.load( code )
|
99
|
+
monofile = new
|
100
|
+
monofile.load( code )
|
101
|
+
monofile
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.load_file( path ) ## keep (or add load_yaml to or such) - why? why not?
|
105
|
+
code = File.open( path, 'r:utf-8') { |f| f.read }
|
106
|
+
load( code )
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
### attr readers
|
111
|
+
def projects() @projects; end
|
112
|
+
def size() @projects.size; end
|
113
|
+
|
114
|
+
|
115
|
+
def initialize( obj={} ) ## todo/fix: change default to obj=[]
|
116
|
+
@projects = []
|
117
|
+
|
118
|
+
## puts "[debug] obj.class=#{obj.class.name}"
|
119
|
+
add( obj )
|
120
|
+
end
|
121
|
+
|
122
|
+
def load( code ) ## note: code is text as a string
|
123
|
+
builder = Builder.new( self )
|
124
|
+
builder.instance_eval( code )
|
125
|
+
self ## note: for chaining always return self
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
def add( obj )
|
130
|
+
## todo/check: check for proc too! and use load( proc/block ) - possible?
|
131
|
+
if obj.is_a?( String )
|
132
|
+
puts "sorry add String - to be done!!!"
|
133
|
+
exit 1
|
134
|
+
elsif obj.is_a?( Array )
|
135
|
+
puts "sorry add Array- to be done!!!"
|
136
|
+
exit 1
|
137
|
+
elsif obj.is_a?( Hash )
|
138
|
+
add_hash( obj )
|
139
|
+
else ## assume text (evaluate/parse)
|
140
|
+
puts "sorry add Text - to be done!!!"
|
141
|
+
exit 1
|
142
|
+
end
|
143
|
+
self ## note: return self for chaining
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def add_hash( hash )
|
148
|
+
hash.each do |org_with_counter, names|
|
149
|
+
|
150
|
+
## remove optional number from key e.g.
|
151
|
+
## mrhydescripts (3) => mrhydescripts
|
152
|
+
## footballjs (4) => footballjs
|
153
|
+
## etc.
|
154
|
+
|
155
|
+
## todo/check: warn about duplicates or such - why? why not?
|
156
|
+
|
157
|
+
org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip.to_s
|
158
|
+
|
159
|
+
names.each do |name|
|
160
|
+
@projects << Project.new( org, name )
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
self ## note: return self for chaining
|
165
|
+
end
|
166
|
+
|
167
|
+
|
168
|
+
|
169
|
+
def each( &block )
|
170
|
+
## puts "[debug] arity: #{block.arity}"
|
171
|
+
|
172
|
+
## for backwards compatibility support "old" each with/by org & names
|
173
|
+
## add deprecated warnings and use to_h or such - why? why not?
|
174
|
+
if block.arity == 2
|
175
|
+
puts "!! DEPRECATED - please, use Monofile#to_h or Monofile.each {|proj| ...}"
|
176
|
+
to_h.each do |org, names|
|
177
|
+
block.call( org, names )
|
178
|
+
end
|
179
|
+
else
|
180
|
+
## assume just regular
|
181
|
+
@projects.each do |project|
|
182
|
+
block.call( project )
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end # method each
|
186
|
+
|
187
|
+
def each_with_index( &block )
|
188
|
+
@projects.each_with_index do |project,i|
|
189
|
+
block.call( project, i )
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
|
194
|
+
|
195
|
+
### for backward compat(ibility) add a hash in the form e.g:
|
196
|
+
##
|
197
|
+
## geraldb:
|
198
|
+
## - austria
|
199
|
+
## - catalog
|
200
|
+
## - geraldb.github.io
|
201
|
+
## - logos
|
202
|
+
## yorobot:
|
203
|
+
## - auto
|
204
|
+
## - backup
|
205
|
+
## - football.json
|
206
|
+
## - logs
|
207
|
+
##
|
208
|
+
def to_h
|
209
|
+
h = {}
|
210
|
+
@projects.each do |project|
|
211
|
+
h[ project.org ] ||= []
|
212
|
+
h[ project.org ] << project.name
|
213
|
+
end
|
214
|
+
h
|
215
|
+
end
|
216
|
+
|
217
|
+
def to_a
|
218
|
+
## todo/check:
|
219
|
+
## - sort all entries a-z - why? why not?
|
220
|
+
## - always start name with @ marker - why? why not?
|
221
|
+
@projects.map {|project| project.to_s }
|
222
|
+
end
|
223
|
+
end # class Monofile
|
224
|
+
|
225
|
+
|
226
|
+
|
@@ -0,0 +1,132 @@
|
|
1
|
+
#####
|
2
|
+
# mononame (e.g. @org/hello) machinery
|
3
|
+
# turn
|
4
|
+
# - @yorobot/stage/one
|
5
|
+
# - one@yorobot/stage
|
6
|
+
# - stage/one@yorobot
|
7
|
+
# => into
|
8
|
+
# - yorobot/stage/one
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
module Mono
|
14
|
+
## shared parse/norm helper (for Name/Path)
|
15
|
+
## - find something better - why? why not?
|
16
|
+
def self.parse_name( line )
|
17
|
+
if line.is_a?( String )
|
18
|
+
parts = line.split( '@' )
|
19
|
+
raise ArgumentError, "[Mononame] no @ found BUT required in name; got >#{line}<" if parts.size == 1
|
20
|
+
raise ArgumentError, "[Mononame] too many @ found (#{parts.size-1}) in name; got >#{line}<" if parts.size > 2
|
21
|
+
|
22
|
+
## pass 1) rebuild (normalized) name/path
|
23
|
+
name = String.new('')
|
24
|
+
name << parts[1] ## add orgs path first - w/o leading @ - gets removed by split :-)
|
25
|
+
if parts[0].length > 0 ## has leading repo name (w/ optional path)
|
26
|
+
name << '/'
|
27
|
+
name << parts[0]
|
28
|
+
end
|
29
|
+
|
30
|
+
## pass 2) split (normalized) name/path into components (org/name/path)
|
31
|
+
parts = name.split( '/' )
|
32
|
+
|
33
|
+
args = [parts[0], parts[1]]
|
34
|
+
|
35
|
+
more_parts = parts[2..-1] ## check for any extra (optional) path parts
|
36
|
+
args << more_parts.join( '/' ) if more_parts.size > 0
|
37
|
+
|
38
|
+
args
|
39
|
+
else
|
40
|
+
raise ArgumentError, "[Mononame] string with @ expected; got: #{line.pretty_inspect} of type #{line.class.name}"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end # module Mono
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
class Mononame
|
48
|
+
def self.parse( line )
|
49
|
+
values = Mono.parse_name( line )
|
50
|
+
raise ArgumentError, "[Mononame] expected two parts (org/name); got #{values.pretty_inspect}" if values.size != 2
|
51
|
+
new( *values )
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
## note: org and name for now required
|
57
|
+
## - make name optional too - why? why not?!!!
|
58
|
+
## use some different names / attributes ??
|
59
|
+
attr_reader :org, ## todo/check: find a different name (or add alias e.g. login/user/etc.)
|
60
|
+
:name
|
61
|
+
|
62
|
+
def initialize( org, name )
|
63
|
+
if org.is_a?(String) && name.is_a?(String)
|
64
|
+
@org = org
|
65
|
+
@name = name
|
66
|
+
else
|
67
|
+
raise ArgumentError, "[Mononame] expected two strings (org, name); got >#{org}< of type #{org.class.name}, >#{name}< of type #{name.class.name}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_path() "#{@org}/#{@name}"; end
|
72
|
+
def to_s() "@#{to_path}"; end
|
73
|
+
end # class Mononame
|
74
|
+
|
75
|
+
|
76
|
+
|
77
|
+
####
|
78
|
+
## todo/check:
|
79
|
+
## use as shared Mono/nomen/resource or such
|
80
|
+
# shared base class for Mononame & Monopath - why? why not?
|
81
|
+
#
|
82
|
+
# Monoloc (for location)
|
83
|
+
# Monores (for resource)
|
84
|
+
# Mono__ ??
|
85
|
+
#
|
86
|
+
# name components:
|
87
|
+
# - better name for path? - use filepath, relpath, ...
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
class Monopath
|
92
|
+
def self.parse( line )
|
93
|
+
values = Mono.parse_name( line )
|
94
|
+
raise ArgumentError, "[Monopath] expected three parts (org/name/path); got #{values.pretty_inspect}" if values.size != 3
|
95
|
+
new( *values )
|
96
|
+
end
|
97
|
+
|
98
|
+
## note: org and name AND path for now required
|
99
|
+
## - make name path optional too - why? why not?!!!
|
100
|
+
attr_reader :org, :name, :path
|
101
|
+
|
102
|
+
def initialize( org, name, path )
|
103
|
+
## support/check for empty path too - why? why not?
|
104
|
+
|
105
|
+
if org.is_a?(String) && name.is_a?(String) && path.is_a?(String)
|
106
|
+
## assume [org, name, path?]
|
107
|
+
## note: for now assumes proper formatted strings
|
108
|
+
## e.g. no leading @ or combined @hello/text in org
|
109
|
+
## or name or such
|
110
|
+
## - use parse/norm_name here too - why? why not?
|
111
|
+
@org = org
|
112
|
+
@name = name
|
113
|
+
@path = path
|
114
|
+
else
|
115
|
+
raise ArgumentError, "[Monopath] expected three strings (org, name, path); got >#{org}< of type #{org.class.name}, >#{name}< of type #{name.class.name}, >#{path}< of type #{path.class.name}"
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def to_path() "#{@org}/#{@name}/#{@path}"; end
|
120
|
+
def to_s() "@#{to_path}"; end
|
121
|
+
end # class Monopath
|
122
|
+
## note: use Monopath - avoid confusion with Monofile (a special file with a list of mono projects)!!!!
|
123
|
+
|
124
|
+
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
## todo/check: add a (global) Mono/Mononame converter - why? why not?
|
129
|
+
##
|
130
|
+
## module Kernel
|
131
|
+
## def Mono( *args ) Mononame.parse( *args ); end
|
132
|
+
## end
|
data/lib/monofile/version.rb
CHANGED
data/test/helper.rb
ADDED
data/test/test_names.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
###
|
2
|
+
# to run use
|
3
|
+
# ruby -I ./lib -I ./test test/test_names.rb
|
4
|
+
|
5
|
+
|
6
|
+
require 'helper'
|
7
|
+
|
8
|
+
|
9
|
+
class TestNames < MiniTest::Test
|
10
|
+
|
11
|
+
def test_parse
|
12
|
+
%w[
|
13
|
+
@yorobot/stage
|
14
|
+
stage@yorobot
|
15
|
+
].each do |line|
|
16
|
+
mono = Mononame.parse( line )
|
17
|
+
|
18
|
+
assert_equal '@yorobot/stage', mono.to_s
|
19
|
+
assert_equal 'yorobot/stage', mono.to_path
|
20
|
+
|
21
|
+
assert_equal 'yorobot', mono.org
|
22
|
+
assert_equal 'stage', mono.name
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
%w[
|
27
|
+
@yorobot/stage/one
|
28
|
+
one@yorobot/stage
|
29
|
+
stage/one@yorobot
|
30
|
+
].each do |line|
|
31
|
+
mono = Monopath.parse( line )
|
32
|
+
|
33
|
+
assert_equal '@yorobot/stage/one', mono.to_s
|
34
|
+
assert_equal 'yorobot/stage/one', mono.to_path
|
35
|
+
|
36
|
+
assert_equal 'yorobot', mono.org
|
37
|
+
assert_equal 'stage', mono.name
|
38
|
+
assert_equal 'one', mono.path
|
39
|
+
end
|
40
|
+
|
41
|
+
%w[
|
42
|
+
@yorobot/stage/one/hello.txt
|
43
|
+
hello.txt@yorobot/stage/one
|
44
|
+
stage/one/hello.txt@yorobot
|
45
|
+
].each do |line|
|
46
|
+
mono = Monopath.parse( line )
|
47
|
+
|
48
|
+
assert_equal '@yorobot/stage/one/hello.txt', mono.to_s
|
49
|
+
assert_equal 'yorobot/stage/one/hello.txt', mono.to_path
|
50
|
+
|
51
|
+
assert_equal 'yorobot', mono.org
|
52
|
+
assert_equal 'stage', mono.name
|
53
|
+
assert_equal 'one/hello.txt', mono.path
|
54
|
+
end
|
55
|
+
end # method test_parse
|
56
|
+
|
57
|
+
|
58
|
+
def test_init
|
59
|
+
mono = Mononame.new( 'yorobot','stage' )
|
60
|
+
|
61
|
+
assert_equal '@yorobot/stage', mono.to_s
|
62
|
+
assert_equal 'yorobot/stage', mono.to_path
|
63
|
+
|
64
|
+
assert_equal 'yorobot', mono.org
|
65
|
+
assert_equal 'stage', mono.name
|
66
|
+
|
67
|
+
|
68
|
+
mono = Monopath.new( 'yorobot', 'stage', 'one' )
|
69
|
+
|
70
|
+
assert_equal '@yorobot/stage/one', mono.to_s
|
71
|
+
assert_equal 'yorobot/stage/one', mono.to_path
|
72
|
+
|
73
|
+
assert_equal 'yorobot', mono.org
|
74
|
+
assert_equal 'stage', mono.name
|
75
|
+
assert_equal 'one', mono.path
|
76
|
+
|
77
|
+
|
78
|
+
## !!!!todo/check/fix!!!!!:
|
79
|
+
## - support 'one', 'hello.txt' too (or only) - why? why not?
|
80
|
+
##
|
81
|
+
## todo/check/fix:
|
82
|
+
## find a better name for path/path? component / part - why? why not?
|
83
|
+
## to_path and path/path? to confusing!!!
|
84
|
+
mono = Monopath.new( 'yorobot', 'stage', 'one/hello.txt' )
|
85
|
+
|
86
|
+
assert_equal '@yorobot/stage/one/hello.txt', mono.to_s
|
87
|
+
assert_equal 'yorobot/stage/one/hello.txt', mono.to_path
|
88
|
+
|
89
|
+
assert_equal 'yorobot', mono.org
|
90
|
+
assert_equal 'stage', mono.name
|
91
|
+
assert_equal 'one/hello.txt', mono.path
|
92
|
+
end # method test_init
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
end # class TestNames
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monofile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
@@ -61,7 +61,11 @@ files:
|
|
61
61
|
- Rakefile
|
62
62
|
- bin/monofile
|
63
63
|
- lib/monofile.rb
|
64
|
+
- lib/monofile/monofile.rb
|
65
|
+
- lib/monofile/mononame.rb
|
64
66
|
- lib/monofile/version.rb
|
67
|
+
- test/helper.rb
|
68
|
+
- test/test_names.rb
|
65
69
|
homepage: https://github.com/rubycoco/git
|
66
70
|
licenses:
|
67
71
|
- Public Domain
|