monofile 0.0.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Manifest.txt +7 -0
- data/README.md +124 -4
- data/Rakefile +5 -3
- data/bin/monofile +17 -0
- data/lib/monofile.rb +63 -1
- data/lib/monofile/monofile.rb +225 -0
- data/lib/monofile/mononame.rb +176 -0
- data/lib/monofile/tool.rb +59 -0
- data/lib/monofile/version.rb +28 -0
- data/test/helper.rb +7 -0
- data/test/test_names.rb +97 -0
- metadata +16 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 547a6deaf1db0ea792b640dcf686fa5788d0de30
|
4
|
+
data.tar.gz: 01fdcf2b3cfc5ddb70eb68dec8a808f0a1edd2e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3358beae7a3a96107e13e4b01d0fa065acb629b131acca5031168b85331ff88463a8f9e5f7fac09de0e28eb18f2380322e6e481857a8ec077cb4e4355240298
|
7
|
+
data.tar.gz: 7c100f51fb8cb143202016b7d129b80fcf20acea7301c117263b09efec99fdf9ffede2ecb0d47cef266d86489e07de0053b6c586c8d572a0d720fb815d395534
|
data/Manifest.txt
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
# monofile - read in/ parse mono
|
1
|
+
# monofile - read in / parse monorepo / mono source tree definitions - a list of git (and github) projects, and more
|
2
2
|
|
3
|
-
* home :: [github.com/rubycoco/
|
4
|
-
* bugs :: [github.com/rubycoco/
|
3
|
+
* home :: [github.com/rubycoco/monos](https://github.com/rubycoco/monos)
|
4
|
+
* bugs :: [github.com/rubycoco/monos/issues](https://github.com/rubycoco/monos/issues)
|
5
5
|
* gem :: [rubygems.org/gems/monofile](https://rubygems.org/gems/monofile)
|
6
6
|
* rdoc :: [rubydoc.info/gems/monofile](http://rubydoc.info/gems/monofile)
|
7
7
|
|
@@ -9,7 +9,127 @@
|
|
9
9
|
|
10
10
|
## Usage
|
11
11
|
|
12
|
-
|
12
|
+
|
13
|
+
Use `Monofile.read` to read in / parse monorepo / mono source tree definitions - supporting a ruby or a yaml format.
|
14
|
+
|
15
|
+
|
16
|
+
Example - `Monofile`:
|
17
|
+
``` ruby
|
18
|
+
project "@openfootball/england"
|
19
|
+
project "@openfootball/world-cup"
|
20
|
+
project "@geraldb/austria"
|
21
|
+
project "@geraldb/geraldb.github.io"
|
22
|
+
|
23
|
+
project "geraldb", "catalog"
|
24
|
+
project "openfootball", "europe"
|
25
|
+
project "openfootball", "south-america"
|
26
|
+
```
|
27
|
+
|
28
|
+
or
|
29
|
+
|
30
|
+
Example - `monofile.yml`:
|
31
|
+
|
32
|
+
``` yaml
|
33
|
+
geraldb:
|
34
|
+
- austria
|
35
|
+
- catalog
|
36
|
+
- geraldb.github.io
|
37
|
+
|
38
|
+
openfootball:
|
39
|
+
- england
|
40
|
+
- europe
|
41
|
+
- south-america
|
42
|
+
- world-cup
|
43
|
+
```
|
44
|
+
|
45
|
+
|
46
|
+
To read use.
|
47
|
+
|
48
|
+
``` ruby
|
49
|
+
monofile = Monofile.read( "./Monofile" )
|
50
|
+
# -or-
|
51
|
+
monofile = Monofile.read( "./monofile.yml" )
|
52
|
+
pp monofile.to_a
|
53
|
+
#=> ["@openfootball/england",
|
54
|
+
# "@openfootball/world-cup",
|
55
|
+
# "@geraldb/austria",
|
56
|
+
# "@geraldb/geraldb.github.io",
|
57
|
+
# "@geraldb/catalog",
|
58
|
+
# "@openfootball/europe"]
|
59
|
+
# "@openfootball/south-america"]
|
60
|
+
|
61
|
+
pp monofile.to_h
|
62
|
+
#=> {"openfootball"=>["england", "world-cup", "europe", "south-america"],
|
63
|
+
# "geraldb" =>["austria", "geraldb.github.io", "catalog"]}
|
64
|
+
|
65
|
+
monofile.each do |proj|
|
66
|
+
puts " #{proj}"
|
67
|
+
end
|
68
|
+
#=> @openfootball/england
|
69
|
+
# @openfootball/world-cup
|
70
|
+
# @geraldb/austria
|
71
|
+
# @geraldb/geraldb.github.io
|
72
|
+
# @geraldb/catalog
|
73
|
+
# @openfootball/europe
|
74
|
+
# @openfootball/south-america
|
75
|
+
|
76
|
+
monofile.size
|
77
|
+
#=> 7
|
78
|
+
```
|
79
|
+
|
80
|
+
and so on. That's it for now.
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
### Troubleshooting / Debugging
|
85
|
+
|
86
|
+
Use the `monofile` command line tool to test reading in of
|
87
|
+
monorepo / mono source tree definitions.
|
88
|
+
Example:
|
89
|
+
|
90
|
+
``` shell
|
91
|
+
# option 1) try to find default name (e.g. Monofile, Monofile.rb, etc.)
|
92
|
+
$ monofile
|
93
|
+
|
94
|
+
# option 2) pass in monofiles
|
95
|
+
$ monofile ./Monofile
|
96
|
+
$ monofile ./monfile.yml
|
97
|
+
# ...
|
98
|
+
```
|
99
|
+
|
100
|
+
Printing the normalized / canonical names of the repo sources. Example.
|
101
|
+
|
102
|
+
```
|
103
|
+
@openfootball/england
|
104
|
+
@openfootball/world-cup
|
105
|
+
@geraldb/austria
|
106
|
+
@geraldb/geraldb.github.io
|
107
|
+
@geraldb/catalog
|
108
|
+
@openfootball/europe
|
109
|
+
@openfootball/south-america
|
110
|
+
```
|
111
|
+
|
112
|
+
|
113
|
+
|
114
|
+
|
115
|
+
## Real-World Usage
|
116
|
+
|
117
|
+
See the [`monos`](https://github.com/rubycoco/monos/tree/master/monos) package that incl. the `mono` (or short `mo`)
|
118
|
+
command line tool lets you run
|
119
|
+
git commands on multiple repo(sitories) with a single command.
|
120
|
+
|
121
|
+
|
122
|
+
## Installation
|
123
|
+
|
124
|
+
Use
|
125
|
+
|
126
|
+
gem install monofile
|
127
|
+
|
128
|
+
or add to your Gemfile
|
129
|
+
|
130
|
+
gem 'monofile'
|
131
|
+
|
132
|
+
|
13
133
|
|
14
134
|
## License
|
15
135
|
|
data/Rakefile
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
require 'hoe'
|
2
|
+
require './lib/monofile/version.rb'
|
3
|
+
|
2
4
|
|
3
5
|
Hoe.spec 'monofile' do
|
4
6
|
|
5
|
-
self.version =
|
7
|
+
self.version = Mono::Module::Monofile::VERSION
|
6
8
|
|
7
|
-
self.summary = "monofile - read in/ parse mono
|
9
|
+
self.summary = "monofile - read in / parse monorepo / mono source tree definitions - a list of git (and github) projects, and more"
|
8
10
|
self.description = summary
|
9
11
|
|
10
|
-
self.urls = { home: 'https://github.com/rubycoco/
|
12
|
+
self.urls = { home: 'https://github.com/rubycoco/monos' }
|
11
13
|
|
12
14
|
self.author = 'Gerald Bauer'
|
13
15
|
self.email = 'opensport@googlegroups.com'
|
data/bin/monofile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
###################
|
4
|
+
# DEV TIPS:
|
5
|
+
#
|
6
|
+
# For local testing run like:
|
7
|
+
#
|
8
|
+
# ruby -Ilib bin/monofile
|
9
|
+
#
|
10
|
+
# Set the executable bit in Linux. Example:
|
11
|
+
#
|
12
|
+
# % chmod a+x bin/monofile
|
13
|
+
#
|
14
|
+
|
15
|
+
require 'monofile'
|
16
|
+
|
17
|
+
Monofile::Tool.main
|
data/lib/monofile.rb
CHANGED
@@ -1,2 +1,64 @@
|
|
1
|
-
|
1
|
+
##
|
2
|
+
## "prelude / prolog " add some common used stdlibs
|
3
|
+
## add more - why? why not?
|
4
|
+
require 'pp'
|
5
|
+
require 'time'
|
6
|
+
require 'date'
|
7
|
+
require 'json'
|
8
|
+
require 'yaml'
|
9
|
+
require 'fileutils'
|
10
|
+
|
11
|
+
require 'uri'
|
12
|
+
require 'net/http'
|
13
|
+
require 'net/https'
|
14
|
+
|
15
|
+
|
16
|
+
require 'optparse' ## used by monofile (built-in test/debug) command line tool
|
17
|
+
|
18
|
+
|
19
|
+
|
20
|
+
#####################
|
21
|
+
# our own code
|
22
|
+
require 'monofile/version' # note: let version always go first
|
23
|
+
require 'monofile/mononame'
|
24
|
+
require 'monofile/monofile'
|
25
|
+
require 'monofile/tool'
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
module Mono
|
30
|
+
|
31
|
+
def self.root ## root of single (monorepo) source tree
|
32
|
+
@@root ||= begin
|
33
|
+
## todo/fix:
|
34
|
+
## check if windows - otherwise use /sites
|
35
|
+
## check if root directory exists?
|
36
|
+
if ENV['MOPATH']
|
37
|
+
## use expand path to make (assure) absolute path - why? why not?
|
38
|
+
File.expand_path( ENV['MOPATH'] )
|
39
|
+
elsif Dir.exist?( 'C:/Sites' )
|
40
|
+
'C:/Sites'
|
41
|
+
else
|
42
|
+
'/sites'
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.root=( path )
|
48
|
+
## use expand path to make (assure) absolute path - why? why not?
|
49
|
+
@@root = File.expand_path( path )
|
50
|
+
end
|
51
|
+
end ## module Mono
|
52
|
+
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
###
|
57
|
+
## add some convenience alias for alternate spelling (CamelCase)
|
58
|
+
MonoName = Mononame
|
59
|
+
MonoPath = Monopath
|
60
|
+
MonoFile = Monofile
|
61
|
+
|
62
|
+
|
63
|
+
puts Mono::Module::Monofile.banner ## say hello
|
2
64
|
|
@@ -0,0 +1,225 @@
|
|
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
|
+
## openfootball:
|
202
|
+
## - england
|
203
|
+
## - europe
|
204
|
+
## - south-america
|
205
|
+
## - world-cup
|
206
|
+
##
|
207
|
+
def to_h
|
208
|
+
h = {}
|
209
|
+
@projects.each do |project|
|
210
|
+
h[ project.org ] ||= []
|
211
|
+
h[ project.org ] << project.name
|
212
|
+
end
|
213
|
+
h
|
214
|
+
end
|
215
|
+
|
216
|
+
def to_a
|
217
|
+
## todo/check:
|
218
|
+
## - sort all entries a-z - why? why not?
|
219
|
+
## - always start name with @ marker - why? why not?
|
220
|
+
@projects.map {|project| project.to_s }
|
221
|
+
end
|
222
|
+
end # class Monofile
|
223
|
+
|
224
|
+
|
225
|
+
|
@@ -0,0 +1,176 @@
|
|
1
|
+
#####
|
2
|
+
# mononame (e.g. @org/hello) machinery
|
3
|
+
# turn
|
4
|
+
# - @openfootball/england/2020-21
|
5
|
+
# - 2020-21@openfootball/england
|
6
|
+
# - england/2020-21@openfootball
|
7
|
+
# => into
|
8
|
+
# - openfootball/england/2020-21
|
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
|
+
def self.real_path( line )
|
55
|
+
## add one-time (quick) usage convenience shortcut
|
56
|
+
mononame = parse( line )
|
57
|
+
mononame.real_path
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
## note: org and name for now required
|
62
|
+
## - make name optional too - why? why not?!!!
|
63
|
+
## use some different names / attributes ??
|
64
|
+
attr_reader :org, ## todo/check: find a different name (or add alias e.g. login/user/etc.)
|
65
|
+
:name
|
66
|
+
|
67
|
+
def initialize( org, name )
|
68
|
+
if org.is_a?(String) && name.is_a?(String)
|
69
|
+
@org = org
|
70
|
+
@name = name
|
71
|
+
else
|
72
|
+
raise ArgumentError, "[Mononame] expected two strings (org, name); got >#{org}< of type #{org.class.name}, >#{name}< of type #{name.class.name}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def to_path() "#{@org}/#{@name}"; end
|
77
|
+
def to_s() "@#{to_path}"; end
|
78
|
+
|
79
|
+
def real_path() "#{Mono.root}/#{to_path}"; end
|
80
|
+
end # class Mononame
|
81
|
+
|
82
|
+
|
83
|
+
|
84
|
+
####
|
85
|
+
## todo/check:
|
86
|
+
## use as shared Mono/nomen/resource or such
|
87
|
+
# shared base class for Mononame & Monopath - why? why not?
|
88
|
+
#
|
89
|
+
# Monoloc (for location)
|
90
|
+
# Monores (for resource)
|
91
|
+
# Mono__ ??
|
92
|
+
#
|
93
|
+
# name components:
|
94
|
+
# - better name for path? - use filepath, relpath, ...
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
class Monopath
|
99
|
+
def self.parse( line )
|
100
|
+
values = Mono.parse_name( line )
|
101
|
+
raise ArgumentError, "[Monopath] expected three parts (org/name/path); got #{values.pretty_inspect}" if values.size != 3
|
102
|
+
new( *values )
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.real_path( line )
|
106
|
+
monopath = parse( line )
|
107
|
+
monopath.real_path
|
108
|
+
end
|
109
|
+
|
110
|
+
|
111
|
+
## note: org and name AND path for now required
|
112
|
+
## - make name path optional too - why? why not?!!!
|
113
|
+
attr_reader :org, :name, :path
|
114
|
+
|
115
|
+
def initialize( org, name, path )
|
116
|
+
## support/check for empty path too - why? why not?
|
117
|
+
|
118
|
+
if org.is_a?(String) && name.is_a?(String) && path.is_a?(String)
|
119
|
+
## assume [org, name, path?]
|
120
|
+
## note: for now assumes proper formatted strings
|
121
|
+
## e.g. no leading @ or combined @hello/text in org
|
122
|
+
## or name or such
|
123
|
+
## - use parse/norm_name here too - why? why not?
|
124
|
+
@org = org
|
125
|
+
@name = name
|
126
|
+
@path = path
|
127
|
+
else
|
128
|
+
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}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def to_path() "#{@org}/#{@name}/#{@path}"; end
|
133
|
+
def to_s() "@#{to_path}"; end
|
134
|
+
|
135
|
+
def real_path() "#{Mono.root}/#{to_path}"; end
|
136
|
+
|
137
|
+
|
138
|
+
## some File-like convenience helpers
|
139
|
+
## e.g. File.exist? => Monopath.exist?
|
140
|
+
## File.open => Monopath.open( ... ) { block }
|
141
|
+
## etc.
|
142
|
+
def self.exist?( line )
|
143
|
+
File.exist?( real_path( line ) )
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
## path always relative to Mono.root
|
148
|
+
## todo/fix: use File.expand_path( path, Mono.root ) - why? why not?
|
149
|
+
## or always enfore "absolut" path e.g. do NOT allow ../ or ./ or such
|
150
|
+
def self.open( line, mode='r:utf-8', &block )
|
151
|
+
path = real_path( line )
|
152
|
+
## make sure path exists if we open for writing/appending - why? why not?
|
153
|
+
if mode[0] == 'w' || mode[0] == 'a'
|
154
|
+
FileUtils.mkdir_p( File.dirname( path ) ) ## make sure path exists
|
155
|
+
end
|
156
|
+
|
157
|
+
File.open( path, mode ) do |file|
|
158
|
+
block.call( file )
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def self.read_utf8( line )
|
163
|
+
open( line, 'r:utf-8') { |file| file.read }
|
164
|
+
end
|
165
|
+
end # class Monopath
|
166
|
+
## note: use Monopath - avoid confusion with Monofile (a special file with a list of mono projects)!!!!
|
167
|
+
|
168
|
+
|
169
|
+
|
170
|
+
|
171
|
+
|
172
|
+
## todo/check: add a (global) Mono/Mononame converter - why? why not?
|
173
|
+
##
|
174
|
+
## module Kernel
|
175
|
+
## def Mono( *args ) Mononame.parse( *args ); end
|
176
|
+
## end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
class Monofile
|
2
|
+
class Tool
|
3
|
+
def self.main( args=ARGV )
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
OptionParser.new do |parser|
|
7
|
+
## note:
|
8
|
+
## you can add many/multiple modules
|
9
|
+
## e.g. -r gitti -r mono etc.
|
10
|
+
parser.on( '-r NAME', '--require NAME') do |name|
|
11
|
+
options[:requires] ||= []
|
12
|
+
options[:requires] << name
|
13
|
+
end
|
14
|
+
## todo/fix:
|
15
|
+
## add --verbose
|
16
|
+
## add -d/--debug
|
17
|
+
end.parse!( args )
|
18
|
+
|
19
|
+
|
20
|
+
if args.size == 0 ## auto-add default arg (monofile)
|
21
|
+
monofile_path = Monofile.find
|
22
|
+
if monofile_path.nil?
|
23
|
+
puts "!! ERROR: no mono configuration file found; looking for #{Monofile::NAMES.join(', ')} in (#{Dir.getwd})"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
args << monofile_path
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
## add check for auto-require (e.g. ./config.rb)
|
31
|
+
if options[:requires] ## use custom (auto-)requires
|
32
|
+
options[:requires].each do |path|
|
33
|
+
puts "[monofile] auto-require >#{path}<..."
|
34
|
+
require( path )
|
35
|
+
end
|
36
|
+
else ## use/try defaults
|
37
|
+
config_path = "./config.rb"
|
38
|
+
if File.exist?( config_path )
|
39
|
+
puts "[monofile] auto-require (default) >#{config_path}<..."
|
40
|
+
require( config_path )
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
args.each do |path|
|
46
|
+
puts "[monofile] reading >#{path}<..."
|
47
|
+
monofile=Monofile.read( path )
|
48
|
+
pp monofile
|
49
|
+
|
50
|
+
## print one project per line
|
51
|
+
puts "---"
|
52
|
+
monofile.each do |proj|
|
53
|
+
puts proj.to_s
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end # method self.main
|
57
|
+
end # (nested) class Tool
|
58
|
+
end # class Monofile
|
59
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
module Mono
|
3
|
+
module Module
|
4
|
+
module Monofile
|
5
|
+
|
6
|
+
MAJOR = 0 ## todo: namespace inside version or something - why? why not??
|
7
|
+
MINOR = 2
|
8
|
+
PATCH = 2
|
9
|
+
VERSION = [MAJOR,MINOR,PATCH].join('.')
|
10
|
+
|
11
|
+
def self.version
|
12
|
+
VERSION
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.banner
|
16
|
+
"monofile/#{VERSION} on Ruby #{RUBY_VERSION} (#{RUBY_RELEASE_DATE}) [#{RUBY_PLATFORM}]"
|
17
|
+
end
|
18
|
+
|
19
|
+
## note: move root to its own namespace to avoid
|
20
|
+
## conflict with Mono.root!!!!
|
21
|
+
def self.root
|
22
|
+
File.expand_path( File.dirname(File.dirname(__FILE__) ))
|
23
|
+
end
|
24
|
+
|
25
|
+
end # module Monofile
|
26
|
+
end # module Module
|
27
|
+
end # module Mono
|
28
|
+
|
data/test/helper.rb
ADDED
data/test/test_names.rb
ADDED
@@ -0,0 +1,97 @@
|
|
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
|
+
@openfootball/england
|
14
|
+
england@openfootball
|
15
|
+
].each do |line|
|
16
|
+
mono = Mononame.parse( line )
|
17
|
+
|
18
|
+
assert_equal '@openfootball/england', mono.to_s
|
19
|
+
assert_equal 'openfootball/england', mono.to_path
|
20
|
+
|
21
|
+
assert_equal 'openfootball', mono.org
|
22
|
+
assert_equal 'england', mono.name
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
%w[
|
27
|
+
@openfootball/england/2020-21
|
28
|
+
2020-21@openfootball/england
|
29
|
+
england/2020-21@openfootball
|
30
|
+
].each do |line|
|
31
|
+
mono = Monopath.parse( line )
|
32
|
+
|
33
|
+
assert_equal '@openfootball/england/2020-21', mono.to_s
|
34
|
+
assert_equal 'openfootball/england/2020-21', mono.to_path
|
35
|
+
|
36
|
+
assert_equal 'openfootball', mono.org
|
37
|
+
assert_equal 'england', mono.name
|
38
|
+
assert_equal '2020-21', mono.path
|
39
|
+
end
|
40
|
+
|
41
|
+
%w[
|
42
|
+
@openfootball/england/2020-21/premierleague.txt
|
43
|
+
2020-21/premierleague.txt@openfootball/england
|
44
|
+
england/2020-21/premierleague.txt@openfootball
|
45
|
+
].each do |line|
|
46
|
+
mono = Monopath.parse( line )
|
47
|
+
|
48
|
+
assert_equal '@openfootball/england/2020-21/premierleague.txt', mono.to_s
|
49
|
+
assert_equal 'openfootball/england/2020-21/premierleague.txt', mono.to_path
|
50
|
+
|
51
|
+
assert_equal 'openfootball', mono.org
|
52
|
+
assert_equal 'england', mono.name
|
53
|
+
assert_equal '2020-21/premierleague.txt', mono.path
|
54
|
+
end
|
55
|
+
end # method test_parse
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
def test_init
|
60
|
+
mono = Mononame.new( 'openfootball','england' )
|
61
|
+
|
62
|
+
assert_equal '@openfootball/england', mono.to_s
|
63
|
+
assert_equal 'openfootball/england', mono.to_path
|
64
|
+
|
65
|
+
assert_equal 'openfootball', mono.org
|
66
|
+
assert_equal 'england', mono.name
|
67
|
+
|
68
|
+
|
69
|
+
mono = Monopath.new( 'openfootball', 'england', '2020-21' )
|
70
|
+
|
71
|
+
assert_equal '@openfootball/england/2020-21', mono.to_s
|
72
|
+
assert_equal 'openfootball/england/2020-21', mono.to_path
|
73
|
+
|
74
|
+
assert_equal 'openfootball', mono.org
|
75
|
+
assert_equal 'england', mono.name
|
76
|
+
assert_equal '2020-21', mono.path
|
77
|
+
|
78
|
+
|
79
|
+
## !!!!todo/check/fix!!!!!:
|
80
|
+
## - support '2020-21', 'premierleague.txt' too (or only) - why? why not?
|
81
|
+
##
|
82
|
+
## todo/check/fix:
|
83
|
+
## find a better name for path/path? component / part - why? why not?
|
84
|
+
## to_path and path/path? to confusing!!!
|
85
|
+
mono = Monopath.new( 'openfootball', 'england', '2020-21/premierleague.txt' )
|
86
|
+
|
87
|
+
assert_equal '@openfootball/england/2020-21/premierleague.txt', mono.to_s
|
88
|
+
assert_equal 'openfootball/england/2020-21/premierleague.txt', mono.to_path
|
89
|
+
|
90
|
+
assert_equal 'openfootball', mono.org
|
91
|
+
assert_equal 'england', mono.name
|
92
|
+
assert_equal '2020-21/premierleague.txt', mono.path
|
93
|
+
end # method test_init
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
end # class TestNames
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: monofile
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gerald Bauer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rdoc
|
@@ -44,10 +44,11 @@ dependencies:
|
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: '3.22'
|
47
|
-
description: monofile - read in/ parse mono
|
48
|
-
github) projects, and more
|
47
|
+
description: monofile - read in / parse monorepo / mono source tree definitions -
|
48
|
+
a list of git (and github) projects, and more
|
49
49
|
email: opensport@googlegroups.com
|
50
|
-
executables:
|
50
|
+
executables:
|
51
|
+
- monofile
|
51
52
|
extensions: []
|
52
53
|
extra_rdoc_files:
|
53
54
|
- CHANGELOG.md
|
@@ -58,8 +59,15 @@ files:
|
|
58
59
|
- Manifest.txt
|
59
60
|
- README.md
|
60
61
|
- Rakefile
|
62
|
+
- bin/monofile
|
61
63
|
- lib/monofile.rb
|
62
|
-
|
64
|
+
- lib/monofile/monofile.rb
|
65
|
+
- lib/monofile/mononame.rb
|
66
|
+
- lib/monofile/tool.rb
|
67
|
+
- lib/monofile/version.rb
|
68
|
+
- test/helper.rb
|
69
|
+
- test/test_names.rb
|
70
|
+
homepage: https://github.com/rubycoco/monos
|
63
71
|
licenses:
|
64
72
|
- Public Domain
|
65
73
|
metadata: {}
|
@@ -84,6 +92,6 @@ rubyforge_project:
|
|
84
92
|
rubygems_version: 2.5.2
|
85
93
|
signing_key:
|
86
94
|
specification_version: 4
|
87
|
-
summary: monofile - read in/ parse mono
|
88
|
-
projects, and more
|
95
|
+
summary: monofile - read in / parse monorepo / mono source tree definitions - a list
|
96
|
+
of git (and github) projects, and more
|
89
97
|
test_files: []
|