Class: Mono::Tool

Inherits:
Object
  • Object
show all
Includes:
Gitti
Defined in:
lib/mono/commands/sync.rb,
lib/mono.rb,
lib/mono/tool.rb,
lib/mono/commands/env.rb,
lib/mono/commands/run.rb,
lib/mono/commands/fetch.rb,
lib/mono/commands/backup.rb,
lib/mono/commands/status.rb

Overview

pass along hash of repos (e.g. monorepo.yml or repos.yml )

Class Method Summary collapse

Class Method Details

.backupObject



5
6
7
8
9
10
11
12
13
14
# File 'lib/mono/commands/backup.rb', line 5

def self.backup
  repos = Mono.monofile

  backup = GitBackup.new

  ## step 2: pass in all repos to backup by using
  ##   1) git clone --mirror or
  ##   2) git remote update  (if local backup already exists)
  backup.backup( repos )
end

.envObject

check environment setup



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/mono/commands/env.rb', line 4

def self.env   ## check environment setup
  puts "Mono.root (MOPATH): >#{Mono.root}<"
  puts "Mono::Module::Tool.root:  >#{Mono::Module::Tool.root}<"
  puts

  ## add ruby version and path - why? why not? e.g.
  ##  ruby:
  ## bin:        C:/ri330/Ruby2.0.0/bin/ruby.exe
  ## version:    ruby 2.3.3p222 (2016-11-21 revision 56859) [i386-mingw32]

  puts "git version:"
  Git.version
  ## Git.config( 'user.name' )
  ## Git.config( 'user.email', show_origin: true )

  ## dump/print all user.* settings e.g. user.name, user.email
  Git.config( /user/, show_origin: true )

  puts
  puts "monofile => (#{Monofile.find}):"
  pp   Mono.monofile
end

.fetchObject



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/mono/commands/fetch.rb', line 4

def self.fetch
  repos = Mono.monofile

  count_orgs  = 0
  count_repos = 0

  total_repos = repos.size


  repos.each do |org,names|

    org_path = "#{Mono.root}/#{org}"

    names.each do |name|
        puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."

        repo = GitHubRepo.new( org, name )  ## owner, name e.g. rubylibs/webservice

        Dir.chdir( org_path ) do
          if Dir.exist?( repo.name )
            GitProject.open( repo.name ) do |proj|
              proj.fetch
            end
          else
            puts "!!  repo not found / missing"
          end
        end

        count_repos += 1
    end
    count_orgs += 1
  end


  ## print stats & changes summary
  puts
  print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
  print "\n"
end

.main(args = ARGV) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/mono/tool.rb', line 5

def self.main( args=ARGV )

  options = {}
  OptionParser.new do |parser|
    ## note:
    ##  you can add many/multiple modules
    ##  e.g. -r gitti -r mono etc.
    parser.on( '-r NAME', '--require NAME') do |name|
      options[:requires] ||= []
      options[:requires] << name
    end
    ## todo/fix:
    ##    add --verbose
    ##    add -d/--debug
  end.parse!( args )


  ## add check for auto-require (e.g. ./config.rb)
  if options[:requires]  ## use custom (auto-)requires
    options[:requires].each do |path|
      puts "[monofile] auto-require >#{path}<..."
      require( path )
    end
  else  ## use/try defaults
    config_path = "./config.rb"
    if File.exist?( config_path )
      puts "[monofile] auto-require (default) >#{config_path}<..."
      require( config_path )
    end
  end


 ## note: for now assume first argument is command
 cmd = if args.size == 0
         'status'   ## make status "default" command
       else
         args.shift   ## remove first (head) element
       end

 ## note: allow shortcut for commands
 case cmd.downcase
 when 'status', 'stati', 'stat', 'st', 's'
    status
 when 'sync', 'syn', 'sy',  ## note: allow aliases such as install, get & up too
      'get', 'g',
      'install', 'insta', 'inst', 'ins', 'i',
      'up', 'u'
    sync
 when 'fetch', 'f'
    fetch
 when 'env', 'e'
    env
 when 'backup', 'back', 'b'
    backup
 when 'run', 'r', 'exec'
    run( args )


 ##################
 ## for debugging / linting
 when 'walk'
    Mono.walk
 else
   puts "!! ERROR: unknown command >#{cmd}<"
   exit 1
 end

end

.run(*args) ⇒ Object



4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/mono/commands/run.rb', line 4

def self.run( *args )
  ## todo/fix: use a "standard" argument to pass along hash of repos
  ##   (e.g. monorepo.yml or repos.yml ) how?  - why? why not?
  repos = Mono.monofile


  cmd = args.join( ' ' )

  count_orgs  = 0
  count_repos = 0

  total_repos = repos.size

  repos.each do |org,names|

    org_path = "#{Mono.root}/#{org}"

    names.each do |name|
        puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."

        repo = GitHubRepo.new( org, name )  ## owner, name e.g. rubylibs/webservice

        Dir.chdir( org_path ) do
          if Dir.exist?( repo.name )
            GitProject.open( repo.name ) do |proj|
              proj.run( cmd )
            end
          else
            puts "!!  repo not found / missing"
          end
        end

        count_repos += 1
    end
    count_orgs += 1
  end


  ## print stats & changes summary
  puts
  print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
  print "\n"
end

.statusObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mono/commands/status.rb', line 5

def self.status
  repos = Mono.monofile

  changes =  []   ## track changes

  count_orgs  = 0
  count_repos = 0

  total_repos = repos.size

  repos.each do |org,names|

    org_path = "#{Mono.root}/#{org}"

    names.each do |name|
        puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."

        repo = GitHubRepo.new( org, name )  ## owner, name e.g. rubylibs/webservice

        Dir.chdir( org_path ) do
          if Dir.exist?( repo.name )
            GitProject.open( repo.name ) do |proj|
              output = proj.changes
              if output.empty?
                 puts "   - no changes -"
              else
                changes << ["#{org}@#{name}", :CHANGES, output]
              end
            end
          else
            puts "!!  repo not found / missing"
            changes << ["#{org}@#{name}", :NOT_FOUND]
          end
        end

        count_repos += 1
    end
    count_orgs += 1
  end


  ## print stats & changes summary
  puts
  print "#{changes.size} change(s) in "
  print "#{count_repos} repo(s) @ #{count_orgs} org(s)"
  print "\n"

  changes.each do |item|
    puts
    print "== #{item[0]} - #{item[1]}"
    case item[1]
    when :CHANGES
      print ":\n"
      print item[2]
    when :NOT_FOUND
      print "\n"
    end
  end

end

.syncObject



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/mono/commands/sync.rb', line 5

def self.sync
  repos = Mono.monofile

  count_orgs  = 0
  count_repos = 0

  total_repos = repos.size

  repos.each do |org,names|
    org_path = "#{Mono.root}/#{org}"
    FileUtils.mkdir_p( org_path ) unless Dir.exist?( org_path )   ## make sure path exists

    names.each do |name|
        puts "[#{count_repos+1}/#{total_repos}] #{org}@#{name}..."

        repo = GitHubRepo.new( org, name )  ## owner, name e.g. rubylibs/webservice

        Dir.chdir( org_path ) do
          if Dir.exist?( repo.name )
            GitProject.open( repo.name ) do |proj|
              if proj.changes?
                puts "!! WARN - local changes in workdir; skipping fast forward (remote) sync / merge"
              else
                proj.fast_forward   ## note: use git pull --ff-only (fast forward only - do NOT merge)
              end
            end
          else
            Git.clone( repo.ssh_clone_url )
          end
        end

#
# todo/fix: add (back) error log !!!!!!!!!!!!
#        rescue GitError => ex
#          puts "!! ERROR: #{ex.message}"
#
#          File.open( './errors.log', 'a' ) do |f|
#              f.write "#{Time.now} -- repo #{org}/#{name} - #{ex.message}\n"
#           end

        count_repos += 1
    end
    count_orgs += 1
  end

  ## print stats
  puts "#{count_repos} repo(s) @ #{count_orgs} org(s)"
end