monos 0.2.1 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,47 @@
1
+ module Mono
2
+
3
+ def self.run( *args )
4
+ ## todo/fix: use a "standard" argument to pass along hash of repos
5
+ ## (e.g. monorepo.yml or repos.yml ) how? - why? why not?
6
+ repos = Mono.monofile
7
+
8
+
9
+ cmd = args.join( ' ' )
10
+
11
+ count_orgs = 0
12
+ count_repos = 0
13
+
14
+ total_repos = repos.size
15
+
16
+ repos.each do |org,names|
17
+
18
+ org_path = "#{Mono.root}/#{org}"
19
+
20
+ names.each do |name|
21
+ puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."
22
+
23
+ repo = GitHubRepo.new( org, name ) ## owner, name e.g. rubylibs/webservice
24
+
25
+ ::Dir.chdir( org_path ) do
26
+ if ::Dir.exist?( repo.name )
27
+ GitProject.open( repo.name ) do |proj|
28
+ proj.run( cmd )
29
+ end
30
+ else
31
+ puts "!! repo not found / missing"
32
+ end
33
+ end
34
+
35
+ count_repos += 1
36
+ end
37
+ count_orgs += 1
38
+ end
39
+
40
+
41
+ ## print stats & changes summary
42
+ puts
43
+ print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
44
+ print "\n"
45
+ end # method run
46
+
47
+ end # module Mono
@@ -1,71 +1,65 @@
1
- module Mono
2
-
3
- ## pass along hash of repos (e.g. monorepo.yml or repos.yml )
4
- def self.status( h=Mono.monofile )
5
- changes = [] ## track changes
6
-
7
- count_orgs = 0
8
- count_repos = 0
9
-
10
- ## sum up total number of repos
11
- total_repos = h.reduce(0) {|sum,(_,names)| sum+= names.size; sum }
12
-
13
-
14
- h.each do |org_with_counter,names|
15
-
16
- ## remove optional number from key e.g.
17
- ## mrhydescripts (3) => mrhydescripts
18
- ## footballjs (4) => footballjs
19
- ## etc.
20
- org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip
21
-
22
- org_path = "#{Mono.root}/#{org}"
23
-
24
- names.each do |name|
25
- puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."
26
-
27
- repo = GitHubRepo.new( org, name ) ## owner, name e.g. rubylibs/webservice
28
-
29
- Dir.chdir( org_path ) do
30
- if Dir.exist?( repo.name )
31
- GitProject.open( repo.name ) do |git|
32
- output = git.changes
33
- if output.empty?
34
- puts " - no changes -"
35
- else
36
- changes << ["#{org}@#{name}", :CHANGES, output]
37
- end
38
- end
39
- else
40
- puts "!! repo not found / missing"
41
- changes << ["#{org}@#{name}", :NOT_FOUND]
42
- end
43
- end
44
-
45
- count_repos += 1
46
- end
47
- count_orgs += 1
48
- end
49
-
50
-
51
- ## print stats & changes summary
52
- puts
53
- print "#{changes.size} change(s) in "
54
- print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
55
- print "\n"
56
-
57
- changes.each do |item|
58
- puts
59
- print "== #{item[0]} - #{item[1]}"
60
- case item[1]
61
- when :CHANGES
62
- print ":\n"
63
- print item[2]
64
- when :NOT_FOUND
65
- print "\n"
66
- end
67
- end
68
-
69
- end # method status
70
-
71
- end # module Mono
1
+ module Mono
2
+
3
+ ## pass along hash of repos (e.g. monorepo.yml or repos.yml )
4
+ def self.status
5
+ repos = Mono.monofile
6
+
7
+ changes = [] ## track changes
8
+
9
+ count_orgs = 0
10
+ count_repos = 0
11
+
12
+ total_repos = repos.size
13
+
14
+ repos.each do |org,names|
15
+
16
+ org_path = "#{Mono.root}/#{org}"
17
+
18
+ names.each do |name|
19
+ puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."
20
+
21
+ repo = GitHubRepo.new( org, name ) ## owner, name e.g. rubylibs/webservice
22
+
23
+ ::Dir.chdir( org_path ) do
24
+ if ::Dir.exist?( repo.name )
25
+ GitProject.open( repo.name ) do |proj|
26
+ output = proj.changes
27
+ if output.empty?
28
+ puts " - no changes -"
29
+ else
30
+ changes << ["#{org}@#{name}", :CHANGES, output]
31
+ end
32
+ end
33
+ else
34
+ puts "!! repo not found / missing"
35
+ changes << ["#{org}@#{name}", :NOT_FOUND]
36
+ end
37
+ end
38
+
39
+ count_repos += 1
40
+ end
41
+ count_orgs += 1
42
+ end
43
+
44
+
45
+ ## print stats & changes summary
46
+ puts
47
+ print "#{changes.size} change(s) in "
48
+ print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
49
+ print "\n"
50
+
51
+ changes.each do |item|
52
+ puts
53
+ print "== #{item[0]} - #{item[1]}"
54
+ case item[1]
55
+ when :CHANGES
56
+ print ":\n"
57
+ print item[2]
58
+ when :NOT_FOUND
59
+ print "\n"
60
+ end
61
+ end
62
+
63
+ end # method status
64
+
65
+ end # module Mono
@@ -1,59 +1,53 @@
1
- module Mono
2
-
3
- ## pass along hash of repos (e.g. monorepo.yml or repos.yml )
4
- def self.sync( h=Mono.monofile )
5
- count_orgs = 0
6
- count_repos = 0
7
-
8
- ## sum up total number of repos
9
- total_repos = h.reduce(0) {|sum,(_,names)| sum+= names.size; sum }
10
-
11
- h.each do |org_with_counter,names|
12
-
13
- ## remove optional number from key e.g.
14
- ## mrhydescripts (3) => mrhydescripts
15
- ## footballjs (4) => footballjs
16
- ## etc.
17
- org = org_with_counter.sub( /\([0-9]+\)/, '' ).strip
18
-
19
- org_path = "#{Mono.root}/#{org}"
20
- FileUtils.mkdir_p( org_path ) unless Dir.exist?( org_path ) ## make sure path exists
21
-
22
- names.each do |name|
23
- puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."
24
-
25
- repo = GitHubRepo.new( org, name ) ## owner, name e.g. rubylibs/webservice
26
-
27
- Dir.chdir( org_path ) do
28
- if Dir.exist?( repo.name )
29
- GitProject.open( repo.name ) do |git|
30
- if git.changes?
31
- puts "!! WARN - local changes in workdir; skipping fast forward (remote) sync / merge"
32
- else
33
- git.fast_forward ## note: use git pull --ff-only (fast forward only - do NOT merge)
34
- end
35
- end
36
- else
37
- Git.clone( repo.ssh_clone_url )
38
- end
39
- end
40
-
41
- #
42
- # todo/fix: add (back) error log !!!!!!!!!!!!
43
- # rescue GitError => ex
44
- # puts "!! ERROR: #{ex.message}"
45
- #
46
- # File.open( './errors.log', 'a' ) do |f|
47
- # f.write "#{Time.now} -- repo #{org}/#{name} - #{ex.message}\n"
48
- # end
49
-
50
- count_repos += 1
51
- end
52
- count_orgs += 1
53
- end
54
-
55
- ## print stats
56
- puts "#{count_repos} repo(s) @ #{count_orgs} org(s)"
57
- end # method sync
58
-
59
- end # module Mono
1
+ module Mono
2
+
3
+ ## pass along hash of repos (e.g. monorepo.yml or repos.yml )
4
+ def self.sync
5
+ repos = Mono.monofile
6
+
7
+ count_orgs = 0
8
+ count_repos = 0
9
+
10
+ total_repos = repos.size
11
+
12
+ repos.each do |org,names|
13
+ org_path = "#{Mono.root}/#{org}"
14
+ ::FileUtils.mkdir_p( org_path ) unless ::Dir.exist?( org_path ) ## make sure path exists
15
+
16
+ names.each do |name|
17
+ puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."
18
+
19
+ repo = GitHubRepo.new( org, name ) ## owner, name e.g. rubylibs/webservice
20
+
21
+ ::Dir.chdir( org_path ) do
22
+ if ::Dir.exist?( repo.name )
23
+ GitProject.open( repo.name ) do |proj|
24
+ if proj.changes?
25
+ puts "!! WARN - local changes in workdir; skipping fast forward (remote) sync / merge"
26
+ else
27
+ proj.fast_forward ## note: use git pull --ff-only (fast forward only - do NOT merge)
28
+ end
29
+ end
30
+ else
31
+ Git.clone( repo.ssh_clone_url )
32
+ end
33
+ end
34
+
35
+ #
36
+ # todo/fix: add (back) error log !!!!!!!!!!!!
37
+ # rescue GitError => ex
38
+ # puts "!! ERROR: #{ex.message}"
39
+ #
40
+ # File.open( './errors.log', 'a' ) do |f|
41
+ # f.write "#{Time.now} -- repo #{org}/#{name} - #{ex.message}\n"
42
+ # end
43
+
44
+ count_repos += 1
45
+ end
46
+ count_orgs += 1
47
+ end
48
+
49
+ ## print stats
50
+ puts "#{count_repos} repo(s) @ #{count_orgs} org(s)"
51
+ end # method sync
52
+
53
+ end # module Mono
@@ -0,0 +1,104 @@
1
+ ##############
2
+ # experimental stuff
3
+ #
4
+
5
+ module Mono
6
+
7
+ ######################
8
+ ### lint/print mono (source) tree
9
+ ### - check for git repos (via .git/ dir)
10
+ #
11
+ # turn into
12
+ # - tree or
13
+ # - lint or
14
+ # - doctor or
15
+ # - check or such command - why? why not?
16
+ def self.walk( path=root)
17
+ repos = walk_dir( path )
18
+ repos
19
+ end
20
+
21
+
22
+ ###############
23
+ # private helpers
24
+ private
25
+
26
+ ## todo/check - use max_depth or max_level or such - why? why not?
27
+ def self.walk_dir( path, repos=[], level=1, depth: nil )
28
+ entries = ::Dir.entries(path)
29
+
30
+ ## filter dirs
31
+ dirs = entries.select do |entry|
32
+ if ['..', '.'].include?( entry ) ## first check for excludes
33
+ false
34
+ else
35
+ full_path = ::File.join( path, entry )
36
+ ::File.directory?( full_path )
37
+ end
38
+ end
39
+
40
+ if dirs.size == 0 ## shortcircuit - no dirs in dir
41
+ return repos
42
+ end
43
+
44
+ repos_count = 0 ## note: local (only) repos count
45
+ warns_count = 0
46
+ sub_dirs = []
47
+
48
+
49
+
50
+ buf = String.new('') ## use an output buffer (allows optional print)
51
+
52
+
53
+ buf << ">#{path}< - level #{level}:\n"
54
+ dirs.each do |entry|
55
+ next if ['..', '.', '.git'].include?( entry )
56
+ full_path = ::File.join( path, entry )
57
+
58
+ if ::Dir.exist?( ::File.join( full_path, '.git' ))
59
+ repos_count += 1
60
+
61
+ if level == 1
62
+ warns_count += 1
63
+ buf << "!! WARN - top-level repo (w/o user/org) >#{entry}< @ #{path}\n"
64
+ end
65
+
66
+ if level > 2
67
+ warns_count += 1
68
+ buf << "!! WARN - hidden (?) sub-level #{level} repo (nested too deep?) >#{entry}< @ #{path}\n"
69
+ end
70
+
71
+ buf << " repo ##{'%-2d' % repos_count} | "
72
+ buf << "#{'%-20s' % entry} @ #{::File.basename(path)} (#{path})"
73
+ buf << "\n"
74
+ repos << full_path
75
+
76
+ ## check for bare bone git repos - todo/fix: add .gitconfig or such and more - why? why not?
77
+ elsif ::Dir.exist?( ::File.join( full_path, 'hooks' )) &&
78
+ ::Dir.exist?( ::File.join( full_path, 'info' )) &&
79
+ ::Dir.exist?( ::File.join( full_path, 'objects' )) &&
80
+ ::Dir.exist?( ::File.join( full_path, 'refs' ))
81
+ warns_count += 1
82
+ buf << "!! WARN - skip bare git repo >#{entry}< @ #{path}\n"
83
+ else
84
+ buf << " x >#{entry}<\n"
85
+ sub_dirs << entry
86
+ end
87
+ end
88
+ buf << " #{repos_count} repos(s), #{dirs.size} dir(s), #{warns_count} warn(s)\n"
89
+ buf << "\n"
90
+
91
+ ## note: skip output of "plain" diretory listings (no repos, no warnings)
92
+ puts buf if repos_count > 0 || warns_count > 0
93
+
94
+
95
+ sub_dirs.each do |entry|
96
+ ## continue walking
97
+ full_path = ::File.join( path, entry )
98
+ walk_dir( full_path, repos, level+1, depth: depth )
99
+ end
100
+
101
+ repos
102
+ end
103
+
104
+ end # module Mono
@@ -1,37 +1,41 @@
1
- module Mono
2
-
3
-
4
- class Tool
5
- def self.main( args=ARGV )
6
-
7
- ## note: for now assume first argument is command
8
- ## add options later
9
-
10
- cmd = if args.size == 0
11
- 'status' ## make status "default" command
12
- else
13
- args.shift ## remove first (head) element
14
- end
15
-
16
- ## note: allow shortcut for commands
17
- case cmd.downcase
18
- when 'status', 'stati', 'stat', 'st', 's'
19
- Mono.status
20
- when 'sync', 'syn', 'sy', ## note: allow aliases such as install, get & up too
21
- 'get', 'g',
22
- 'install', 'insta', 'inst', 'ins', 'i',
23
- 'up', 'u'
24
- Mono.sync
25
- when 'fetch', 'f'
26
- Mono.fetch
27
- when 'env', 'e'
28
- Mono.env
29
- else
30
- puts "!! ERROR: unknown command >#{cmd}<"
31
- exit 1
32
- end
33
-
34
- end # method self.main
35
- end # class Tool
36
-
1
+ module Mono
2
+
3
+
4
+ class Tool
5
+ def self.main( args=ARGV )
6
+
7
+ ## note: for now assume first argument is command
8
+ ## add options later
9
+
10
+ cmd = if args.size == 0
11
+ 'status' ## make status "default" command
12
+ else
13
+ args.shift ## remove first (head) element
14
+ end
15
+
16
+ ## note: allow shortcut for commands
17
+ case cmd.downcase
18
+ when 'status', 'stati', 'stat', 'st', 's'
19
+ Mono.status
20
+ when 'sync', 'syn', 'sy', ## note: allow aliases such as install, get & up too
21
+ 'get', 'g',
22
+ 'install', 'insta', 'inst', 'ins', 'i',
23
+ 'up', 'u'
24
+ Mono.sync
25
+ when 'fetch', 'f'
26
+ Mono.fetch
27
+ when 'env', 'e'
28
+ Mono.env
29
+ when 'backup', 'back', 'b'
30
+ Mono.backup
31
+ when 'run', 'r', 'exec'
32
+ Mono.run( args )
33
+ else
34
+ puts "!! ERROR: unknown command >#{cmd}<"
35
+ exit 1
36
+ end
37
+
38
+ end # method self.main
39
+ end # class Tool
40
+
37
41
  end # module Mono