Module: Kintsugi

Defined in:
lib/kintsugi/error.rb,
lib/kintsugi.rb,
lib/kintsugi/cli.rb,
lib/kintsugi/merge.rb,
lib/kintsugi/version.rb,
lib/kintsugi/settings.rb,
lib/kintsugi/conflict_resolver.rb,
lib/kintsugi/apply_change_to_project.rb

Overview

Copyright © 2022 Lightricks. All rights reserved. Created by Ben Yohay. frozen_string_literal: true

Defined Under Namespace

Modules: Version Classes: CLI, ConflictResolver, MergeError, Settings

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.apply_change_to_project(project, change, change_source_project) ⇒ void

This method returns an undefined value.



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
# File 'lib/kintsugi/apply_change_to_project.rb', line 42

def apply_change_to_project(project, change, change_source_project)
  return unless change&.key?("rootObject")

  @change_source_project = change_source_project
  @ignored_components_group_paths = []
  @created_components_group_paths = []

  # We iterate over the main group and project references first because they might create file
  # or project references that are referenced in other parts.
  unless change["rootObject"]["mainGroup"].nil?
    if project.root_object.main_group.nil?
      puts "Warning: Main group doesn't exist, ignoring changes to it."
    else
      apply_main_group_change(project, change["rootObject"]["mainGroup"])
    end
  end

  unless change["rootObject"]["projectReferences"].nil?
    apply_change_to_component(project.root_object, "projectReferences",
                              change["rootObject"]["projectReferences"], "rootObject")
  end

  apply_change_to_component(project, "rootObject",
                            change["rootObject"].reject { |key|
                              %w[mainGroup projectReferences].include?(key)
                            }, "")
end

.resolve_conflicts(project_file_path, changes_output_path) ⇒ void

This method returns an undefined value.

Resolves git conflicts of a pbxproj file specified by ‘project_file_path`.

Parameters:

  • project_file_path (String)

    Project to which to apply the changes.

  • changes_output_path (String)

    Path to where the changes to apply to the project are written in JSON format.

Raises:

  • (ArgumentError)

    If the file extension is not ‘pbxproj`, or the file doesn’t exist, or if no rebase, cherry-pick, or merge is in progress

  • (MergeError)

    If there was an error applying the change to the project.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/kintsugi/merge.rb', line 32

def resolve_conflicts(project_file_path, changes_output_path)
  validate_project(project_file_path)

  base_project = copy_project_from_stage_number_to_temporary_directory(project_file_path, 1)
  ours_project = copy_project_from_stage_number_to_temporary_directory(project_file_path, 2)
  theirs_project = copy_project_from_stage_number_to_temporary_directory(project_file_path, 3)

  change = Xcodeproj::Differ.project_diff(theirs_project, base_project, :added, :removed)

  if changes_output_path
    File.write(changes_output_path, JSON.pretty_generate(change))
  end

  apply_change_and_copy_to_original_path(ours_project, change, project_file_path,
                                         theirs_project)
end

.run(arguments) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/kintsugi.rb', line 12

def run(arguments)
  first_argument = arguments[0]
  cli = CLI.new
  command =
    if name_of_subcommand?(cli.subcommands, first_argument)
      arguments.shift
      cli.subcommands[first_argument]
    else
      cli.root_command
    end

  options = parse_options!(command, arguments)

  begin
    command.action.call(options, arguments)
  rescue ArgumentError => e
    puts "#{e.class}: #{e}"
    raise
  rescue Kintsugi::MergeError => e
    puts e
    raise
  end
end

.three_way_merge(base_project_path, ours_project_path, theirs_project_path, original_project_path) ⇒ void

This method returns an undefined value.

Merges the changes done between ‘theirs_project_path` and `base_project_path` to the file at `ours_project_path`. The files may not be at the original path, and therefore the `original_project_path` is required in order for the project metadata to be written properly.

Parameters:

  • base_project_path (String)

    Path to the base version of the project.

  • ours_project_path (String)

    Path to ours version of the project.

  • theirs_project_path (String)

    Path to theirs version of the project.

  • original_project_path (String)

    Path to the original path of the file.

Raises:

  • (MergeError)

    If there was an error applying the change to the project.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/kintsugi/merge.rb', line 69

def three_way_merge(base_project_path, ours_project_path, theirs_project_path,
                    original_project_path)
  original_directory_name = File.basename(File.dirname(original_project_path))
  base_temporary_project =
    copy_project_to_temporary_path_in_directory_with_name(base_project_path,
                                                          original_directory_name)
  ours_temporary_project =
    copy_project_to_temporary_path_in_directory_with_name(ours_project_path,
                                                          original_directory_name)
  theirs_temporary_project =
    copy_project_to_temporary_path_in_directory_with_name(theirs_project_path,
                                                          original_directory_name)

  change =
    Xcodeproj::Differ.project_diff(theirs_temporary_project, base_temporary_project,
                                   :added, :removed)

  apply_change_and_copy_to_original_path(ours_temporary_project, change, ours_project_path,
                                         theirs_temporary_project)
end

Instance Method Details

#file_reference_key(change) ⇒ Object



146
147
148
# File 'lib/kintsugi/apply_change_to_project.rb', line 146

def file_reference_key(change)
  [change["name"], change["path"], change["sourceTree"]]
end