From 739a8d6e8ccddb9423af1cd2ca7f93ea0a10c14a Mon Sep 17 00:00:00 2001 From: Sam Dods Date: Mon, 2 Feb 2015 17:35:49 +0000 Subject: [PATCH 1/3] =?UTF-8?q?added=20=E2=80=9Cwarn=20only=E2=80=9D=20opt?= =?UTF-8?q?ion.=20this=20can=20be=20added=20as=20a=20Xcode=20build=20phase?= =?UTF-8?q?=20to=20inform=20the=20developer=20before=20every=20build.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit you can convert these warnings to errors by substituting “warning” for “error” in the output using `sed` as follows: ``` sync -w Example.xcodeproj | perl -p -e “s/warning: /error: /“ ``` --- bin/synx | 3 ++- lib/synx/project.rb | 4 +++- .../project/object/pbx_file_reference.rb | 18 ++++++++++++------ .../xcodeproj_ext/project/object/pbx_group.rb | 6 +++--- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/bin/synx b/bin/synx index 2fb7b1c..ef14d94 100755 --- a/bin/synx +++ b/bin/synx @@ -6,6 +6,7 @@ require 'synx' Clamp do parameter "xcodeproj", "Path to the xcodeproj", :attribute_name => :xcodeproj_path + option ["--warn-only", "-w"], :flag, "show warnings for files whose paths do not match the project structure, but do not make any changes" option ["--prune", "-p"], :flag, "remove source files and image resources that are not referenced by the the xcode project" option "--no-color", :flag, "removes all color from the output" option "--no-default-exclusions", :flag, "doesn't use the default exclusions of /Libraries, /Frameworks, and /Products" @@ -21,7 +22,7 @@ Clamp do puts "You cannot run Synx as root.".red else project = Synx::Project.open(xcodeproj_path) - project.sync(:prune => prune?, :quiet => quiet?, :no_color => no_color?, :no_default_exclusions => no_default_exclusions?, :group_exclusions => exclusion_list) + project.sync(:warn_only_non_destructive => warn_only?, :prune => prune?, :quiet => quiet?, :no_color => no_color?, :no_default_exclusions => no_default_exclusions?, :group_exclusions => exclusion_list) end end diff --git a/lib/synx/project.rb b/lib/synx/project.rb index ce175cc..f6b8fbe 100644 --- a/lib/synx/project.rb +++ b/lib/synx/project.rb @@ -17,7 +17,9 @@ def sync(options={}) presync_check Synx::Tabber.increase Synx::Tabber.puts "Syncing files that are included in Xcode project...".bold.white - main_group.all_groups.each { |gr| gr.sync(main_group) } + warn_only = options[:warn_only_non_destructive] + main_group.all_groups.each { |gr| gr.sync(main_group, warn_only) } + return if warn_only==true Synx::Tabber.puts "\n\n" Synx::Tabber.puts "Syncing files that are not included in Xcode project..".bold.white main_group.all_groups.each(&:move_entries_not_in_xcodeproj) diff --git a/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb b/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb index a95a6f4..0442cc0 100644 --- a/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb +++ b/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb @@ -3,20 +3,26 @@ class Project module Object class PBXFileReference - def sync(group) + def sync(group, warn_only) if should_sync? if should_move? - FileUtils.mv(real_path.to_s, work_pathname.to_s) - # TODO: move out to abstract_object - self.source_tree = "" - self.path = work_pathname.relative_path_from(parent.work_pathname).to_s + if !warn_only + FileUtils.mv(real_path.to_s, work_pathname.to_s) + # TODO: move out to abstract_object + self.source_tree = "" + self.path = work_pathname.relative_path_from(parent.work_pathname).to_s + else + cmd = "echo '#{real_path.to_s}:1: warning: Path on disk does not match project group structure.'" + errors = `#{cmd}` + puts errors + end else # Don't move this file around -- it's not even inside the structure. Just fix the relative reference self.path = real_path.relative_path_from((project.work_pathname_to_pathname(group.work_pathname))).to_s end change_build_settings_reference - output + output unless warn_only else Synx::Tabber.puts "skipped #{basename}".red end diff --git a/lib/synx/xcodeproj_ext/project/object/pbx_group.rb b/lib/synx/xcodeproj_ext/project/object/pbx_group.rb index 1eadaaa..d6c198e 100644 --- a/lib/synx/xcodeproj_ext/project/object/pbx_group.rb +++ b/lib/synx/xcodeproj_ext/project/object/pbx_group.rb @@ -3,7 +3,7 @@ class Project module Object class PBXGroup - def sync(group) + def sync(group, warn_only) ensure_internal_consistency(group) # Make sure we don't belong to any other groups if excluded_from_sync? Synx::Tabber.puts "#{basename}/ (excluded)".yellow @@ -17,11 +17,11 @@ def sync(group) # inside the loops. files.each do |pbx_file| pbx_file.work_pathname.dirname.mkpath - pbx_file.sync(self) + pbx_file.sync(self, warn_only) end all_groups.each do |group| group.work_pathname.dirname.mkpath - group.sync(self) + group.sync(self, warn_only) end sync_path From ff0823221dbb7dcc37934bfdf774cfd28721a7ef Mon Sep 17 00:00:00 2001 From: Sam Dods Date: Tue, 10 Feb 2015 10:23:14 +0000 Subject: [PATCH 2/3] =?UTF-8?q?refactored=20=E2=80=9C--warn-only=E2=80=9D?= =?UTF-8?q?=20to=20allow=20ability=20to=20pass=20=E2=80=9Cwarning=E2=80=9D?= =?UTF-8?q?=20or=20=E2=80=9Cerror=E2=80=9D=20depending=20on=20the=20desire?= =?UTF-8?q?d=20result?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/synx | 4 ++-- lib/synx/project.rb | 20 ++++++++++++++++--- .../project/object/pbx_file_reference.rb | 15 ++++++++------ .../xcodeproj_ext/project/object/pbx_group.rb | 8 +++++--- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/bin/synx b/bin/synx index ef14d94..0da71d6 100755 --- a/bin/synx +++ b/bin/synx @@ -6,7 +6,7 @@ require 'synx' Clamp do parameter "xcodeproj", "Path to the xcodeproj", :attribute_name => :xcodeproj_path - option ["--warn-only", "-w"], :flag, "show warnings for files whose paths do not match the project structure, but do not make any changes" + option ["--warn-type", "-w"], "warning|error", "show warnings or errors for files whose paths do not match the project structure. Using this option will not make any changes to the project. Use it as an Xcode build phase to alert the developer.", :attribute_name => :warn_type option ["--prune", "-p"], :flag, "remove source files and image resources that are not referenced by the the xcode project" option "--no-color", :flag, "removes all color from the output" option "--no-default-exclusions", :flag, "doesn't use the default exclusions of /Libraries, /Frameworks, and /Products" @@ -22,7 +22,7 @@ Clamp do puts "You cannot run Synx as root.".red else project = Synx::Project.open(xcodeproj_path) - project.sync(:warn_only_non_destructive => warn_only?, :prune => prune?, :quiet => quiet?, :no_color => no_color?, :no_default_exclusions => no_default_exclusions?, :group_exclusions => exclusion_list) + project.sync(:warn_type => warn_type, :prune => prune?, :quiet => quiet?, :no_color => no_color?, :no_default_exclusions => no_default_exclusions?, :group_exclusions => exclusion_list) end end diff --git a/lib/synx/project.rb b/lib/synx/project.rb index f6b8fbe..a5f765a 100644 --- a/lib/synx/project.rb +++ b/lib/synx/project.rb @@ -17,9 +17,13 @@ def sync(options={}) presync_check Synx::Tabber.increase Synx::Tabber.puts "Syncing files that are included in Xcode project...".bold.white - warn_only = options[:warn_only_non_destructive] - main_group.all_groups.each { |gr| gr.sync(main_group, warn_only) } - return if warn_only==true + warn_type = warn_type_from_options(options) + isError = false + main_group.all_groups.each do |gr| + isError = gr.sync(main_group, warn_type) || isError + end + exit -1 if isError + return if warn_type != nil Synx::Tabber.puts "\n\n" Synx::Tabber.puts "Syncing files that are not included in Xcode project..".bold.white main_group.all_groups.each(&:move_entries_not_in_xcodeproj) @@ -28,6 +32,16 @@ def sync(options={}) save end + def warn_type_from_options(options) + return nil if !options[:warn_type] + warn_type = options[:warn_type] + if warn_type != "warning" && warn_type != "error" + raise "Invalid warning type `#{warn_type}`" + end + return warn_type + end + private :warn_type_from_options + def presync_check forward_slash_groups = main_group.groups_containing_forward_slash unless forward_slash_groups.empty? diff --git a/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb b/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb index 0442cc0..5e370d4 100644 --- a/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb +++ b/lib/synx/xcodeproj_ext/project/object/pbx_file_reference.rb @@ -3,18 +3,20 @@ class Project module Object class PBXFileReference - def sync(group, warn_only) + def sync(group, warn_type) + isError = false if should_sync? if should_move? - if !warn_only + if !warn_type FileUtils.mv(real_path.to_s, work_pathname.to_s) # TODO: move out to abstract_object self.source_tree = "" self.path = work_pathname.relative_path_from(parent.work_pathname).to_s else - cmd = "echo '#{real_path.to_s}:1: warning: Path on disk does not match project group structure.'" - errors = `#{cmd}` - puts errors + cmd = "echo '#{real_path.to_s}:1: #{warn_type}: Path on disk does not match project group structure.'" + warnings = `#{cmd}` + puts warnings + isError = (warnings.length > 0 && warn_type == "error") end else # Don't move this file around -- it's not even inside the structure. Just fix the relative reference @@ -22,10 +24,11 @@ def sync(group, warn_only) end change_build_settings_reference - output unless warn_only + output if warn_type == nil else Synx::Tabber.puts "skipped #{basename}".red end + return isError end def output diff --git a/lib/synx/xcodeproj_ext/project/object/pbx_group.rb b/lib/synx/xcodeproj_ext/project/object/pbx_group.rb index d6c198e..4362fc4 100644 --- a/lib/synx/xcodeproj_ext/project/object/pbx_group.rb +++ b/lib/synx/xcodeproj_ext/project/object/pbx_group.rb @@ -3,8 +3,9 @@ class Project module Object class PBXGroup - def sync(group, warn_only) + def sync(group, warn_type) ensure_internal_consistency(group) # Make sure we don't belong to any other groups + isError = false if excluded_from_sync? Synx::Tabber.puts "#{basename}/ (excluded)".yellow else @@ -17,16 +18,17 @@ def sync(group, warn_only) # inside the loops. files.each do |pbx_file| pbx_file.work_pathname.dirname.mkpath - pbx_file.sync(self, warn_only) + isError = pbx_file.sync(self, warn_type) || isError end all_groups.each do |group| group.work_pathname.dirname.mkpath - group.sync(self, warn_only) + isError = group.sync(self, warn_type) || isError end sync_path Synx::Tabber.decrease end + return isError end def excluded_from_sync? From adf4061480e824279acef0749b80cebc9d8b1cec Mon Sep 17 00:00:00 2001 From: Sam Dods Date: Tue, 10 Feb 2015 10:50:54 +0000 Subject: [PATCH 3/3] added unit tests for warn only option --- spec/synx/original_file_structure.yml | 44 +++++++++++++++++++++++++++ spec/synx/project_spec.rb | 16 +++++++++- 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 spec/synx/original_file_structure.yml diff --git a/spec/synx/original_file_structure.yml b/spec/synx/original_file_structure.yml new file mode 100644 index 0000000..f43eba0 --- /dev/null +++ b/spec/synx/original_file_structure.yml @@ -0,0 +1,44 @@ +dummy: + AlreadySynced: + Core Data.xcdatamodeld: + .xccurrentversion: + Core Data.xcdatamodel: + contents: + Core Data 2.xcdatamodel: + contents: + Core Data 3.xcdatamodel: + contents: + Core Data 4.xcdatamodel: + contents: + FolderNotInXcodeProj: + AnotherFileNotInXcodeProj.h: + NSObject+abc.h: + NSObject+abc.m: + Wowwww.h: + Wowwww.m: + Woot.h: + Woot.m: + stuff.xml: + FileNotInXcodeProj.h + ManyFiles.h + ManyFiles.m + Wow.h + Wow.m + data.json + dummy-Prefix.pch + dummy.h + dummy.m + en.lproj: + Localizable.strings: + de.lproj: + Localizable.strings: + folderWithGroupNotLinked: + data.json + image-not-in-xcodeproj.png: + image.png: +dummyTests: + dummyTests-Info.plist: + dummyTests-prefix.pch: + dummyTests.m: + en.lproj: + InfoPlist.strings: diff --git a/spec/synx/project_spec.rb b/spec/synx/project_spec.rb index 0a1cbad..6c3b414 100644 --- a/spec/synx/project_spec.rb +++ b/spec/synx/project_spec.rb @@ -92,6 +92,10 @@ def expected_group_structure YAML::load_file(File.expand_path("../expected_group_structure.yml", __FILE__)) end + def original_file_structure + YAML::load_file(File.expand_path("../original_file_structure.yml", __FILE__)) + end + describe "with no additional options" do before(:all) do @@ -121,6 +125,16 @@ def expected_group_structure end end + describe "with warnings only option enabled" do + before(:all) do + DUMMY_SYNX_TEST_PROJECT.sync(:prune => true, :output => StringIO.new) + end + + it "should not make any changes to file structure" do + verify_file_structure(Pathname(DUMMY_SYNX_TEST_PROJECT_PATH).parent, original_file_structure) + end + end + describe "with the prune option toggled" do before(:all) do @@ -235,4 +249,4 @@ def expected_group_structure expect(value).to eq(expected) end end -end \ No newline at end of file +end