check_xcode_xmls 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c81381382ef0b3eaee3a268b0e65e20c08d549fe
4
+ data.tar.gz: 7e61924751d164938ff6feeed6a13a0ef9d49f2f
5
+ SHA512:
6
+ metadata.gz: b6f9e57fc93518f3086acd5c825ed790b7b53ff1f7b4b27d9a2d3595e9316a9ae668a99e13d04aa76bc6aeeb5ec8704e4a95d4e076cc53cdecdd72d867cceaef
7
+ data.tar.gz: 86598a83f9b6b5e229e9bb35495857c4783b64b5c7a058d85f473efd2d00898bfba07a15bd9e4ebc7a56bba0c59e7d8a9f3d3bef7ecbc52ee1c4cacacb4c76ce
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'check_xcode_xmls'
5
+
6
+ ::CheckXcodeXmls.main(ARGV)
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'check_xcode_xmls'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,74 @@
1
+ require 'optparse'
2
+
3
+ # https://docs.ruby-lang.org/en/2.1.0/OptionParser.html
4
+ Options = Struct.new(
5
+ :input_directory,
6
+ :ignore_regex_string,
7
+ :check_constraints_identifiers,
8
+ :check_use_autolayout
9
+ )
10
+
11
+ SCRIPT_NAME = 'check-xcode-xmls'.freeze
12
+
13
+ # Parses command line arguments
14
+ class Parser
15
+ def self.default_options
16
+ result = Options.new
17
+ result.input_directory = '.'
18
+ result.check_constraints_identifiers = false
19
+ result.check_use_autolayout = false
20
+ result
21
+ end
22
+ private_class_method :default_options
23
+
24
+ def self.parse(argv)
25
+ # If no arguments supplied, print help
26
+ argv << '-h' if argv.empty?
27
+
28
+ result = default_options
29
+
30
+ options_parser = OptionParser.new do |o|
31
+ o.banner = 'Usage: {SCRIPT_NAME} [input directory]'
32
+ # nandrei add an ignore option.
33
+ o.on('-h',
34
+ '--help',
35
+ 'Prints this help') do
36
+ puts options_parser
37
+ exit 0
38
+ end
39
+ o.on('-iIGNORE',
40
+ '--ignore-regex=IGNORE',
41
+ 'Case sensitive ignore files regex. Eg. "Ignore|Debug"') do |v|
42
+ result.ignore_regex_string = v
43
+ end
44
+
45
+ o.on('--check-constraints-identifiers',
46
+ 'Check files for constraints that don\'t have identifiers') do |_v|
47
+ result.check_constraints_identifiers = true
48
+ end
49
+
50
+ o.on('--check-use-autolayout',
51
+ 'Find files which don\'t use autolayout') do |_v|
52
+ result.check_use_autolayout = true
53
+ end
54
+ end
55
+
56
+ begin
57
+ options_parser.parse!(argv)
58
+ rescue StandardError => exception
59
+ puts exception
60
+ puts options_parser
61
+ exit 1
62
+ end
63
+
64
+ result.input_directory = argv.pop
65
+ if result.input_directory.nil? || !Dir.exist?(result.input_directory)
66
+ directory = result.input_directory || ''
67
+ puts 'Can\'t find directory ' + directory
68
+ Parser.parse %w[--help]
69
+ exit 0
70
+ end
71
+
72
+ result
73
+ end
74
+ end
@@ -0,0 +1,93 @@
1
+ require 'find'
2
+
3
+ class XcodeXml
4
+ def self.extension
5
+ 'implement in subclass'
6
+ end
7
+
8
+ def self.check_if_file_uses_autolayout(file, doc_xpath)
9
+ # <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch"
10
+ # propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
11
+ if doc_xpath.attribute('useAutolayout').nil?
12
+ return ["#{file}: doesn't use autolayout."]
13
+ end
14
+ nil
15
+ end
16
+
17
+ def self.search_constraints_without_identifiers(file, doc_xpath)
18
+ result = []
19
+ doc_xpath.children.each do |child|
20
+ array = search_constraints_without_identifiers(file, child)
21
+ # puts '----'
22
+ # puts child
23
+ if child.name == 'constraint'
24
+ if child.attr('identifier').nil?
25
+ array.push("#{file}: constraint with id #{child.attr('id')} doesn't have an identifier.")
26
+ end
27
+ end
28
+ result += array unless array.nil?
29
+ end
30
+ result
31
+ end
32
+ end
33
+
34
+ class Xib < XcodeXml
35
+ def self.extension
36
+ /.xib$/
37
+ end
38
+ end
39
+
40
+ class Storyboard < XcodeXml
41
+ def self.extension
42
+ /.storyboard$/
43
+ end
44
+ # eg. segue identifier
45
+ end
46
+
47
+ # Convenience utilities.
48
+
49
+ def find_files(ignore_regex_string, base_path, extension)
50
+ file_paths = []
51
+ ignore_regex = Regexp.new(ignore_regex_string) unless ignore_regex_string.nil?
52
+ # puts ignore_regex
53
+ Find.find(base_path) do |path|
54
+ next if File.directory? path
55
+ next if path !~ extension
56
+ if ignore_regex
57
+ next if path =~ ignore_regex
58
+ end
59
+
60
+ file_paths << path
61
+ end
62
+ file_paths
63
+ end
64
+
65
+ require 'nokogiri'
66
+ def parse_xml(
67
+ check_constraints_identifiers,
68
+ check_use_autolayout,
69
+ file
70
+ )
71
+ string = File.open(file, 'r:UTF-8').read
72
+ doc = Nokogiri::XML(string)
73
+ # puts doc.xpath('document').attribute('type')
74
+ result = []
75
+
76
+ [Xib,
77
+ Storyboard].each do |item|
78
+
79
+ next if file !~ item.extension
80
+
81
+ if check_constraints_identifiers
82
+ constraintsValues = item.search_constraints_without_identifiers(file, doc.xpath('document'))
83
+ result += constraintsValues unless constraintsValues.nil?
84
+ end
85
+
86
+ if check_use_autolayout
87
+ autolayoutValue = item.check_if_file_uses_autolayout(file, doc.xpath('document'))
88
+ result += autolayoutValue unless autolayoutValue.nil?
89
+ end
90
+ end
91
+ # result = search_constraints_without_identifiers(file, doc.xpath('document'))
92
+ result
93
+ end
@@ -0,0 +1,23 @@
1
+ require_relative 'helpers'
2
+
3
+ # Adapter which handles shell access.
4
+ class ShellAdapter
5
+ def process_files(
6
+ check_constraints_identifiers,
7
+ check_use_autolayout,
8
+ ignore_regex_string,
9
+ base_path
10
+ )
11
+ result = []
12
+ files = find_files(ignore_regex_string, base_path, /.(xib|storyboard)$/)
13
+
14
+ files.each do |file|
15
+ result += parse_xml(
16
+ check_constraints_identifiers,
17
+ check_use_autolayout,
18
+ file
19
+ )
20
+ end
21
+ result
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module CheckXcodeXmls
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,27 @@
1
+ require 'check_xcode_xmls/version'
2
+ require 'check_xcode_xmls/arguments_parser.rb'
3
+ require 'check_xcode_xmls/shell_adapter.rb'
4
+
5
+ module CheckXcodeXmls
6
+ class Error < StandardError; end
7
+ # Your code goes here...
8
+
9
+ def self.main(args)
10
+ arguments_string = args.join(' ')
11
+ options = Parser.parse(args)
12
+
13
+ shell = ShellAdapter.new
14
+ result = shell.process_files(
15
+ options.check_constraints_identifiers,
16
+ options.check_use_autolayout,
17
+ options.ignore_regex_string,
18
+ options.input_directory
19
+ )
20
+
21
+ puts "#{$PROGRAM_NAME} #{arguments_string}"
22
+ puts "Total issues: #{result.length || 0}"
23
+ puts result unless result.nil?
24
+ end
25
+ end
26
+
27
+ # TODO: nandrei make switches for each operation
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: check_xcode_xmls
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrei Nagy
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: nokogiri
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: Check interface builder files for autolayout constraints without identifiers.
70
+ email:
71
+ - nagy.andrei@gmail.com
72
+ executables:
73
+ - check-xcode-xmls
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - bin/check-xcode-xmls
78
+ - bin/console
79
+ - bin/setup
80
+ - lib/check_xcode_xmls.rb
81
+ - lib/check_xcode_xmls/arguments_parser.rb
82
+ - lib/check_xcode_xmls/helpers.rb
83
+ - lib/check_xcode_xmls/shell_adapter.rb
84
+ - lib/check_xcode_xmls/version.rb
85
+ homepage: https://github.com/andreinagy/check-xcode-xmls
86
+ licenses:
87
+ - MIT
88
+ metadata:
89
+ allowed_push_host: https://rubygems.org
90
+ post_install_message:
91
+ rdoc_options: []
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.5.2.3
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: Check that constraints in storyboards and xibs have constraints identifiers.
110
+ test_files: []