Class: Refinement::Analyzer
- Inherits:
-
Object
- Object
- Refinement::Analyzer
- Defined in:
- lib/refinement/analyzer.rb
Overview
Analyzes changes in a repository and determines how those changes impact the targets in Xcode projects in the workspace.
Instance Method Summary collapse
-
#annotate_targets! ⇒ Array<AnnotatedTarget>
Targets from the projects annotated with their changes, based upon the changeset.
-
#filtered_scheme(scheme_path:, change_level: :full_transitive, filter_when_scheme_has_changed: false, log_changes: false, filter_scheme_for_build_action:) ⇒ Xcodeproj::XCScheme
A scheme whose unchanged targets have been removed.
-
#format_changes(include_unchanged_targets: false, change_level: :full_transitive) ⇒ String
A string suitable for user display that explains target changes.
-
#initialize(changeset:, workspace_path:, projects: nil, augmenting_paths_yaml_files:, augmenting_paths_by_target: nil) ⇒ Analyzer
constructor
Initializes an analyzer with a changeset, projects, and augmenting paths.
Constructor Details
#initialize(changeset:, workspace_path:, projects: nil, augmenting_paths_yaml_files:, augmenting_paths_by_target: nil) ⇒ Analyzer
Initializes an analyzer with a changeset, projects, and augmenting paths.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/refinement/analyzer.rb', line 25 def initialize(changeset:, workspace_path:, projects: nil, augmenting_paths_yaml_files:, augmenting_paths_by_target: nil) @changeset = changeset raise ArgumentError, 'Can only specify one of workspace_path and projects' if workspace_path && projects @workspace_path = workspace_path @projects = projects raise ArgumentError, 'Can only specify one of augmenting_paths_yaml_files and augmenting_paths_by_target' if augmenting_paths_yaml_files && augmenting_paths_by_target @augmenting_paths_yaml_files = augmenting_paths_yaml_files @augmenting_paths_by_target = augmenting_paths_by_target end |
Instance Method Details
#annotate_targets! ⇒ Array<AnnotatedTarget>
Returns targets from the projects annotated with their changes, based upon the changeset.
43 44 45 |
# File 'lib/refinement/analyzer.rb', line 43 def annotate_targets! @annotate_targets ||= annotated_targets end |
#filtered_scheme(scheme_path:, change_level: :full_transitive, filter_when_scheme_has_changed: false, log_changes: false, filter_scheme_for_build_action:) ⇒ Xcodeproj::XCScheme
Returns a scheme whose unchanged targets have been removed.
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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/refinement/analyzer.rb', line 61 def filtered_scheme(scheme_path:, change_level: :full_transitive, filter_when_scheme_has_changed: false, log_changes: false, filter_scheme_for_build_action:) scheme = Xcodeproj::XCScheme.new(scheme_path) sections_to_filter = case filter_scheme_for_build_action when :building %w[BuildActionEntry TestableReference] when :testing # don't want to filter out build action entries running # xcodebuild build-for-testing / test, since the test action could have a macro expansion # that depends upon one of the build targets. %w[TestableReference] else raise ArgumentError, 'The supported values for the `filter_scheme_for_build_action` parameter are: [:building, :testing]. ' \ "Given: #{filter_scheme_for_build_action.inspect}." end if filter_when_scheme_has_changed || !UsedPath.new(path: Pathname(scheme_path), inclusion_reason: 'scheme').find_in_changeset(changeset) changes_by_suite_name = Hash[annotate_targets! .map { |at| [at.xcode_target.name, at.change_reason(level: change_level)] }] doc = scheme.doc xpaths = sections_to_filter.map { |section| "//*/#{section}/BuildableReference" } xpaths.each do |xpath| doc.get_elements(xpath).to_a.each do |buildable_reference| suite_name = buildable_reference.attributes['BlueprintName'] if (change_reason = changes_by_suite_name[suite_name]) puts "#{suite_name} changed because #{change_reason}" if log_changes next end puts "#{suite_name} did not change, removing from scheme" if log_changes buildable_reference.parent.remove end end end scheme end |
#format_changes(include_unchanged_targets: false, change_level: :full_transitive) ⇒ String
Returns a string suitable for user display that explains target changes.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/refinement/analyzer.rb', line 108 def format_changes(include_unchanged_targets: false, change_level: :full_transitive) annotate_targets!.group_by { |target| target.xcode_target.project.path.to_s }.sort_by(&:first) .map do |project, annotated_targets| changes = annotated_targets.sort_by { |annotated_target| annotated_target.xcode_target.name } .map do |annotated_target| change_reason = annotated_target.change_reason(level: change_level) next if !include_unchanged_targets && !change_reason change_reason ||= 'did not change' "\t#{annotated_target.xcode_target}: #{change_reason}" end.compact "#{project}:\n#{changes.join("\n")}" unless changes.empty? end.compact.join("\n") end |