summaryrefslogtreecommitdiff
path: root/lib/tasks/gitlab/git.rake
blob: 3f5dd2ae3b3d4004c423f098f593e05dab491a90 (plain)
1
2
3
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
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
namespace :gitlab do
  namespace :git do
    desc "GitLab | Git | Repack"
    task repack: :environment do
      failures = perform_git_cmd(%W(#{Gitlab.config.git.bin_path} repack -a --quiet), "Repacking repo")
      if failures.empty?
        puts "Done".color(:green)
      else
        output_failures(failures)
      end
    end

    desc "GitLab | Git | Run garbage collection on all repos"
    task gc: :environment do
      failures = perform_git_cmd(%W(#{Gitlab.config.git.bin_path} gc --auto --quiet), "Garbage Collecting")
      if failures.empty?
        puts "Done".color(:green)
      else
        output_failures(failures)
      end
    end

    desc "GitLab | Git | Prune all repos"
    task prune: :environment do
      failures = perform_git_cmd(%W(#{Gitlab.config.git.bin_path} prune), "Git Prune")
      if failures.empty?
        puts "Done".color(:green)
      else
        output_failures(failures)
      end
    end

    desc 'GitLab | Git | Check all repos integrity'
    task fsck: :environment do
      failures = perform_git_cmd(%W(#{Gitlab.config.git.bin_path} fsck --name-objects --no-progress), "Checking integrity") do |repo|
        check_config_lock(repo)
        check_ref_locks(repo)
      end

      if failures.empty?
        puts "Done".color(:green)
      else
        output_failures(failures)
      end
    end

    def perform_git_cmd(cmd, message)
      puts "Starting #{message} on all repositories"

      failures = []
      all_repos do |repo|
        if system(*cmd, chdir: repo)
          puts "Performed #{message} at #{repo}"
        else
          failures << repo
        end

        yield(repo) if block_given?
      end

      failures
    end

    def output_failures(failures)
      puts "The following repositories reported errors:".color(:red)
      failures.each { |f| puts "- #{f}" }
    end

    def check_config_lock(repo_dir)
      config_exists = File.exist?(File.join(repo_dir, 'config.lock'))
      config_output = config_exists ? 'yes'.color(:red) : 'no'.color(:green)

      puts "'config.lock' file exists?".color(:yellow) + " ... #{config_output}"
    end

    def check_ref_locks(repo_dir)
      lock_files = Dir.glob(File.join(repo_dir, 'refs/heads/*.lock'))

      if lock_files.present?
        puts "Ref lock files exist:".color(:red)

        lock_files.each { |lock_file| puts "  #{lock_file}" }
      else
        puts "No ref lock files exist".color(:green)
      end
    end
  end
end