Module: GitTree

Defined in:
lib/git_tree.rb

Class Method Summary collapse

Class Method Details

.command_evars(root = ARGV[0]) ⇒ Object

Parameters:

  • root (defaults to: ARGV[0])

    might be “$envar” or a fully qualified directory name (“/a/b/c”)



7
8
9
10
11
12
13
14
15
# File 'lib/git_tree.rb', line 7

def self.command_evars(root = ARGV[0])
  abort "Error: Argument must start with a dollar sign ($)" unless root.start_with? '$'

  base = MslinnUtil.expand_env root
  dirs = directories_to_process base

  # puts "# root=#{root}, base=#{base}"
  puts make_env_vars root, base, dirs
end

.command_replicate(root = ARGV[0]) ⇒ Object

Parameters:

  • root (defaults to: ARGV[0])

    might be “$envar” or a fully qualified directory name (“/a/b/c”)



18
19
20
21
22
23
24
25
26
# File 'lib/git_tree.rb', line 18

def self.command_replicate(root = ARGV[0])
  abort "Error: Argument must start with a dollar sign ($)" unless root.start_with? '$'

  base = MslinnUtil.expand_env root
  dirs = directories_to_process base

  # puts "# root=#{root}, base=#{base}"
  puts make_replicate_script root, base, dirs
end

.directories_to_process(root) ⇒ Object

Returns array containing directory names to process Each directory name ends with a slash, to ensure symlinks are dereferences.

Returns:

  • array containing directory names to process Each directory name ends with a slash, to ensure symlinks are dereferences



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/git_tree.rb', line 30

def self.directories_to_process(root)
  root_fq = File.expand_path root
  abort "Error: #{root_fq} is a file, instead of a directory. Cannot recurse." if File.file? root_fq

  root_fq = MslinnUtil.deref_symlink(root_fq).to_s
  abort "Error: #{root_fq} does not exist. Halting." unless Dir.exist? root_fq

  result = []
  Find.find(root_fq) do |path|
    next if File.file? path

    Find.prune if File.exist?("#{path}/.ignore")

    if Dir.exist?("#{path}/.git")
      result << path.to_s
      Find.prune
    end
  end
  result.map { |x| x.delete_prefix("#{root_fq}/") }
end

.env_var_name(path) ⇒ Object



51
52
53
54
# File 'lib/git_tree.rb', line 51

def self.env_var_name(path)
  name = path.include?('/') ? File.basename(path) : path
  name.tr(' ', '_').tr('-', '_')
end

.help(msg = nil) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/git_tree.rb', line 56

def self.help(msg = nil)
  puts msg if msg
  puts <<~END_HELP
    Replicates tree of git repos and writes a bash script to STDOUT that clones the repos in the tree.
    Adds upstream remotes as required.

    Directories containing a file called .ignore are ignored.
  END_HELP
  exit 1
end

.make_env_var(name, value) ⇒ Object



67
68
69
# File 'lib/git_tree.rb', line 67

def self.make_env_var(name, value)
  "export #{env_var_name(name)}=#{value}"
end

.make_env_vars(root, base, dirs) ⇒ Object

Parameters:

  • root

    might be “$envar” or a fully qualified directory name (“/a/b/c”)

  • base

    a fully qualified directory name (“/a/b/c”)

  • dirs

    directory list to process



74
75
76
77
78
79
80
81
82
83
# File 'lib/git_tree.rb', line 74

def self.make_env_vars(root, base, dirs)
  result = []
  result << "cat <<EOF >> #{root}/.evars"
  result << make_env_var(env_var_name(base), MslinnUtil.deref_symlink(base))
  dirs.each do |dir|
    result << make_env_var(env_var_name(dir), "#{root}/#{dir}")
  end
  result << "EOF\n"
  result.join "\n"
end

.make_replicate_script(root, base, dirs) ⇒ Object

Parameters:

  • root

    might be “$envar” or a fully qualified directory name (“/a/b/c”)

  • base

    a fully qualified directory name (“/a/b/c”)

  • dirs

    directory list to process



88
89
90
91
92
93
94
95
# File 'lib/git_tree.rb', line 88

def self.make_replicate_script(root, base, dirs)
  help "Error: Please specify the subdirectory to traverse.\n\n" if root.to_s.empty?

  Dir.chdir(base) do
    result = dirs.map { |dir| replicate_one(dir) }
    result.join "\n"
  end
end

.replicate_one(dir) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/git_tree.rb', line 97

def self.replicate_one(dir)
  output = []
  project_dir = File.basename dir
  parent_dir = File.dirname dir
  repo = Rugged::Repository.new dir
  origin_url = repo.config['remote.origin.url']

  output << "if [ ! -d \"#{dir}/.git\" ]; then"
  output << "  mkdir -p '#{parent_dir}'"
  output << "  pushd '#{parent_dir}' > /dev/null"
  output << "  git clone #{origin_url}"

  repo.remotes.each do |remote|
    next if remote.name == 'origin' || remote.url == 'no_push'

    output << "  git remote add #{remote.name} '#{remote.url}'"
  end

  output << '  popd > /dev/null'

  # git_dir_name = File.basename Dir.pwd
  # if git_dir_name != project_dir
  #   output << '  # Git project directory was renamed, renaming this copy to match original directory structure'
  #   output << "  mv #{git_dir_name} #{project_dir}"
  # end
  output << "fi"
  output << ''
  output
end