Class: Fastlane::Actions::EnsureGitStatusCleanAction

Inherits:
Fastlane::Action show all
Defined in:
fastlane/lib/fastlane/actions/ensure_git_status_clean.rb

Overview

Raises an exception and stop the lane execution if the repo is not in a clean state

Constant Summary

Constants inherited from Fastlane::Action

Fastlane::Action::AVAILABLE_CATEGORIES, Fastlane::Action::RETURN_TYPES

Class Method Summary collapse

Methods inherited from Fastlane::Action

action_name, authors, deprecated_notes, lane_context, method_missing, other_action, return_type, return_value, sample_return_value, shell_out_should_use_bundle_exec?, step_text

Class Method Details

.authorObject



75
76
77
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 75

def self.author
  ["lmirosevic", "antondomashnev"]
end

.available_optionsObject



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 85

def self.available_options
  [
    FastlaneCore::ConfigItem.new(key: :show_uncommitted_changes,
                                 env_name: "FL_ENSURE_GIT_STATUS_CLEAN_SHOW_UNCOMMITTED_CHANGES",
                                 description: "The flag whether to show uncommitted changes if the repo is dirty",
                                 optional: true,
                                 default_value: false,
                                 type: Boolean),
    FastlaneCore::ConfigItem.new(key: :show_diff,
                                 env_name: "FL_ENSURE_GIT_STATUS_CLEAN_SHOW_DIFF",
                                 description: "The flag whether to show the git diff if the repo is dirty",
                                 optional: true,
                                 default_value: false,
                                 type: Boolean),
    FastlaneCore::ConfigItem.new(key: :ignored,
                                 env_name: "FL_ENSURE_GIT_STATUS_CLEAN_IGNORED_FILE",
                                 description: [
                                   "The handling mode of the ignored files. The available options are: `'traditional'`, `'none'` (default) and `'matching'`.",
                                   "Specifying `'none'` to this parameter is the same as not specifying the parameter at all, which means that no ignored file will be used to check if the repo is dirty or not.",
                                   "Specifying `'traditional'` or `'matching'` causes some ignored files to be used to check if the repo is dirty or not (more info in the official docs: https://git-scm.com/docs/git-status#Documentation/git-status.txt---ignoredltmodegt)"
                                 ].join(" "),
                                 optional: true,
                                 verify_block: proc do |value|
                                   mode = value.to_s
                                   modes = %w(traditional none matching)

                                   UI.user_error!("Unsupported mode, must be: #{modes}") unless modes.include?(mode)
                                 end),
    FastlaneCore::ConfigItem.new(key: :ignore_files,
                                 env_name: "FL_ENSURE_GIT_STATUS_CLEAN_IGNORE_FILES",
                                 description: "Array of files to ignore",
                                 optional: true,
                                 type: Array)
  ]
end

.categoryObject



121
122
123
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 121

def self.category
  :source_control
end

.descriptionObject



57
58
59
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 57

def self.description
  "Raises an exception if there are uncommitted git changes"
end

.detailsObject



61
62
63
64
65
66
67
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 61

def self.details
  [
    "A sanity check to make sure you are working in a repo that is clean.",
    "Especially useful to put at the beginning of your Fastfile in the `before_all` block, if some of your other actions will touch your filesystem, do things to your git repo, or just as a general reminder to save your work.",
    "Also needed as a prerequisite for some other actions like `reset_git_repo`."
  ].join("\n")
end

.example_codeObject



79
80
81
82
83
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 79

def self.example_code
  [
    'ensure_git_status_clean'
  ]
end

.is_supported?(platform) ⇒ Boolean

Returns:



125
126
127
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 125

def self.is_supported?(platform)
  true
end

.outputObject



69
70
71
72
73
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 69

def self.output
  [
    ['GIT_REPO_WAS_CLEAN_ON_START', 'Stores the fact that the git repo was clean at some point']
  ]
end

.run(params) ⇒ Object



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
# File 'fastlane/lib/fastlane/actions/ensure_git_status_clean.rb', line 9

def self.run(params)
  # Build command
  if params[:ignored]
    ignored_mode = params[:ignored]
    ignored_mode = 'no' if ignored_mode == 'none'
    command = "git status --porcelain --ignored='#{ignored_mode}'"
  else
    command = "git status --porcelain"
  end

  # Don't log if manually ignoring files as it will emulate output later
  print_output = params[:ignore_files].nil?
  repo_status = Actions.sh(command, log: print_output)

  # Manual post processing trying to ignore certain file paths
  if (ignore_files = params[:ignore_files])
    repo_status = repo_status.lines.reject do |line|
      path = line.split(' ').last
      was_found = ignore_files.include?(path)

      UI.message("Ignoring '#{path}'") if was_found

      was_found
    end.join("")

    # Emulate the output format of `git status --porcelain`
    UI.command(command)
    repo_status.lines.each do |line|
      UI.message("" + line.chomp.magenta)
    end
  end

  repo_clean = repo_status.empty?

  if repo_clean
    UI.success('Git status is clean, all good! 💪')
    Actions.lane_context[SharedValues::GIT_REPO_WAS_CLEAN_ON_START] = true
  else
    error_message = "Git repository is dirty! Please ensure the repo is in a clean state by committing/stashing/discarding all changes first."
    error_message += "\nUncommitted changes:\n#{repo_status}" if params[:show_uncommitted_changes]
    if params[:show_diff]
      repo_diff = Actions.sh("git diff")
      error_message += "\nGit diff: \n#{repo_diff}"
    end
    UI.user_error!(error_message)
  end
end