xcselect 0.1.3 → 0.1.4

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.
data/.gitignore CHANGED
@@ -1,2 +1,3 @@
1
1
  .bundle
2
2
  Gemfile.lock
3
+ pkg
data/README.md CHANGED
@@ -48,7 +48,10 @@ Open documents folder for last built app
48
48
 
49
49
  $ xcsim -d
50
50
 
51
+ Open Caches folder for last built app
51
52
 
53
+ $ xcsim -c
54
+
52
55
  Add -p before any of these and xcsim will print the path.
53
56
 
54
57
  If there will be only 1 item to select from the menu will not be displayed and that item will be implicitly selected.
data/bin/xcselect CHANGED
@@ -4,26 +4,7 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
4
4
 
5
5
  require 'xcselect'
6
6
  require 'optparse'
7
-
8
- class String
9
- def red; colorize(self, "\e[1m\e[31m"); end
10
- def dark_red; colorize(self, "\e\[31m"); end
11
- def green; colorize(self, "\e[1m\e[32m"); end
12
- def dark_green; colorize(self, "\e[32m"); end
13
- def yellow; colorize(self, "\e[1m\e[33m"); end
14
- def dark_yellow; colorize(self, "\e[33m"); end
15
- def blue; colorize(self, "\e[1m\e[34m"); end
16
- def dark_blue; colorize(self, "\e[34m"); end
17
- def pur; colorize(self, "\e[1m\e[35m"); end
18
- def dark_pur; colorize(self, "\e[35m"); end
19
- def colorize(text, color_code)
20
- (STDIN.tty?) ? "#{color_code}#{text}\e[0m" : text
21
- end
22
-
23
- def numeric?
24
- true if Float(self) rescue false
25
- end
26
- end
7
+ require "xcselect/string_colors.rb"
27
8
 
28
9
  include Xcselect
29
10
 
data/bin/xcsim CHANGED
@@ -5,35 +5,58 @@ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
5
5
  require 'xcselect'
6
6
  require "fileutils"
7
7
  require "optparse"
8
+ require "xcselect/string_colors.rb"
8
9
 
9
10
  include Xcselect
11
+
12
+ class XcSelectInvalidSelectionException < Exception; end
13
+
14
+
10
15
  class Main
11
16
  attr_reader :exit_code
17
+ attr_accessor :command
18
+ attr_reader :optparse
12
19
  def initialize
13
20
  @options = default_options
14
21
  @exit_code = 0
15
- optparse = OptionParser.new do |opts|
16
- opts.on('-h', '--help', "Display this !!") { puts opts; exit }
17
- opts.on('-v', '--version', "Print version info") { puts "xcselect-" + VERSION; exit; }
18
-
22
+ @optparse = OptionParser.new do |opts|
19
23
  opts.on('-p', '--print', "print the path instead of opening it") { @options[:print] = true }
20
- opts.on('-c', '--cd', "cd into the directory (spawns new shell, type `exit` to return) ") { @options[:print] = false; @options[:cd] = true }
24
+ opts.on('-t', '--touch-app' , "touch app so it becomes latest") { @options[:touch_app] = true }
25
+ opts.on('--cd', "cd into the directory (spawns new shell, type `exit` to return) ") { @options[:print] = false; @options[:cd] = true }
21
26
 
22
- opts.on('-a', '--apps' , "Show list of apps") { show_apps(); exit }
23
- opts.on('-d', '--latest-documents' , "Reveal last built app's documents folder") { show_latest_docs() ;exit}
24
- opts.on('-n', '--latest-newsstand' , "Show list of newsstand issues for last built app") { show_latest_newsstand(); exit }
27
+ # Commands
28
+ opts.on('-h', '--help', "Display this !!") { self.command = :show_help }
29
+ opts.on('-v', '--version', "Print version info") { self.command = :show_version }
30
+ opts.on('-d', '--latest-documents' , "Reveal last built app's documents folder") { self.command = :show_latest_docs}
31
+ opts.on('-n', '--latest-newsstand' , "Show list of newsstand issues for last built app") { self.command = :show_latest_newsstand }
32
+ opts.on('-c', '--latest-cache' , "Reveal last built app's cache folder") { self.command = :show_latest_cache }
33
+ opts.on('-a', '--apps' , "Show list of apps") { self.command = :show_apps ;}
25
34
  end
26
35
  begin
27
36
  optparse.parse!
37
+ run
28
38
  rescue OptionParser::InvalidOption => e
29
39
  puts "Invalid Option"
30
40
  puts optparse
31
41
  exit 2
42
+ rescue XcSelectInvalidSelectionException => e
43
+ puts "xcsim: #{e}"
32
44
  end
33
45
  end
34
46
 
47
+ def command=(c)
48
+ return @command = c if @command.nil?
49
+ @exit_code = 4
50
+ raise XcSelectInvalidSelectionException, "Please use only one command"
51
+ end
52
+
53
+ def run
54
+ send(command || :show_apps)
55
+ end
56
+
57
+
35
58
  def default_options
36
- {:print => false}
59
+ {:print => false, :touch_app => false}
37
60
  end
38
61
 
39
62
  def open_path p
@@ -45,17 +68,15 @@ class Main
45
68
  elsif @options[:print]
46
69
  puts p
47
70
  else
48
- `open -R "#{p}"`
71
+ `open -R "#{p}"`
49
72
  end
50
73
  end
51
74
 
75
+
52
76
  def select_menu title, selections
53
- i = 0
54
- puts title
55
- puts ""
56
- selections.each do |opt|
57
- i += 1
58
- puts " [#{i}] #{opt}"
77
+ puts "#{title}\n\n"
78
+ selections.each_with_index do |opt,i|
79
+ puts " [#{i+1}] #{opt}"
59
80
  end
60
81
  print "\nSelection: "
61
82
  begin
@@ -63,8 +84,8 @@ class Main
63
84
  input = STDIN.gets
64
85
  input = input.to_i
65
86
  if input.zero? or input > selections.size
66
- puts "Invalid Selection"
67
87
  @exit_code = 1
88
+ raise XcSelectInvalidSelectionException, "Invalid Selection"
68
89
  else
69
90
  yield input - 1
70
91
  end
@@ -80,24 +101,32 @@ class Main
80
101
  def show_latest_newsstand
81
102
  latest_app = XcApp.last_built_newsstand_app
82
103
  ns_issues = latest_app.newsstand_objects
83
- issue_paths = latest_app.newsstand_issue_paths
84
104
  issue_names = ns_issues.keys
85
105
  if issue_names.size == 1
86
106
  puts "opening only issue #{issue_names.last}" unless @options[:print]
87
- open_path ns_issues.last[issue_names.last]
107
+ open_path ns_issues.values.last.content_path
88
108
  return
89
109
  end
90
110
  select_menu("Select issue in #{latest_app} to open:", issue_names) {|i|
91
- open_path ns_issues.values[i]
111
+ open_path ns_issues.values[i].content_path
92
112
  }
93
113
 
94
114
  end
95
115
 
116
+ def show_latest_cache
117
+ app = XcApp.last_built_app
118
+ open_path app.cache_path
119
+ end
120
+
96
121
  def show_latest_docs
97
122
  app = XcApp.last_built_app
98
123
  open_path app.documents_path
99
124
  end
100
125
 
126
+ def touch_app app
127
+ FileUtils.touch app.path
128
+ end
129
+
101
130
  def show_apps
102
131
  apps = XcApp.all_apps.sort
103
132
  return @exit_code = 1 if apps.size == 0
@@ -105,9 +134,37 @@ class Main
105
134
  puts "opening only app #{apps}" unless @options[:print]
106
135
  open_path issue_paths.last
107
136
  end
108
- select_menu("Select an app to open:", apps.map(&:to_s)) do |selected_index|
109
- open_path(apps[selected_index].base_dir)
137
+
138
+ last_app = XcApp.sort_by_touch_time(apps).last
139
+ last_newsstand_app = apps.select(&:newsstand?).last
140
+ same_last_app = last_app.equal? last_newsstand_app
141
+
142
+ options = apps.map do |a|
143
+ s = a.to_s
144
+ if a.equal? last_app
145
+ s += " " + (same_last_app ? "[latest]".green : "[latest]".blue)
146
+ elsif a.equal? last_newsstand_app
147
+ s += "[latest-ns]".yellow
148
+ end
149
+ s
110
150
  end
151
+
152
+ select_menu("Select an app to open:", options) do |selected_index|
153
+ selected_app = apps[selected_index]
154
+ if @options[:touch_app]
155
+ touch_app selected_app
156
+ else
157
+ open_path(selected_app.base_dir)
158
+ end
159
+ end
160
+ end
161
+
162
+ def show_help
163
+ puts @optparse
164
+ end
165
+
166
+ def show_version
167
+ puts "xcselect-" + VERSION
111
168
  end
112
169
  end
113
170
 
@@ -0,0 +1,55 @@
1
+
2
+ module Xcselect
3
+ require "plist"
4
+
5
+ # Seams apple stores there internal dates with the base of 2001-01-01
6
+ NSTimeIntervalSince1970 = 978307200.0
7
+
8
+ class NKIssue
9
+ include Comparable
10
+ attr_accessor :name
11
+ attr_accessor :uuid
12
+ attr_accessor :date
13
+ attr_accessor :content_path
14
+
15
+ def self.find_class_key hash
16
+ hash['$objects'].index(hash['$objects'].select{|o| o['$classname'] == "NKIssue"}.first)
17
+ end
18
+
19
+ def self.parse file_name
20
+ ns_plist = Plist::parse_xml(read_bin_plist_to_xml(file_name))
21
+ # this is the integer that we will use to filter all archived nkissue objects
22
+ nk_issue_key = find_class_key(ns_plist)
23
+
24
+ # filter just the nkissue hashes
25
+ object_array = ns_plist['$objects']
26
+ obj_key_hashs = object_array.select{|o| o.class == Hash && o['$class'] && nk_issue_key == o['$class']['CF$UID'] }
27
+
28
+ issues = {}
29
+ obj_key_hashs.each do |nskey|
30
+ issue = NKIssue.new
31
+ issue.name = object_array[nskey['name']['CF$UID']]
32
+ issue.uuid = object_array[nskey['directory']['CF$UID']]
33
+ issue.date = self.archive_time_to_time(object_array[nskey['date']['CF$UID']]['NS.time'])
34
+ issues[issue.name] = issue # unless name.nil?
35
+ end
36
+ return issues
37
+ end
38
+
39
+ def to_s
40
+ "<NKIssue:#{name}:#{date} #{uuid}>"
41
+ end
42
+
43
+ # convert a date offset from 2001 to epoch
44
+ def self.archive_time_to_time t
45
+ Time.at(t + NSTimeIntervalSince1970)
46
+ end
47
+
48
+ def self.read_bin_plist_to_xml plist_path
49
+ `plutil -convert xml1 -o - '#{plist_path}'`
50
+ end
51
+
52
+ end
53
+
54
+ end
55
+
@@ -0,0 +1,19 @@
1
+ class String
2
+ def red; colorize(self, "\e[1m\e[31m"); end
3
+ def dark_red; colorize(self, "\e\[31m"); end
4
+ def green; colorize(self, "\e[1m\e[32m"); end
5
+ def dark_green; colorize(self, "\e[32m"); end
6
+ def yellow; colorize(self, "\e[1m\e[33m"); end
7
+ def dark_yellow; colorize(self, "\e[33m"); end
8
+ def blue; colorize(self, "\e[1m\e[34m"); end
9
+ def dark_blue; colorize(self, "\e[34m"); end
10
+ def pur; colorize(self, "\e[1m\e[35m"); end
11
+ def dark_pur; colorize(self, "\e[35m"); end
12
+ def colorize(text, color_code)
13
+ (STDIN.tty?) ? "#{color_code}#{text}\e[0m" : text
14
+ end
15
+
16
+ def numeric?
17
+ true if Float(self) rescue false
18
+ end
19
+ end
@@ -1,3 +1,3 @@
1
1
  module Xcselect
2
- VERSION = "0.1.3"
2
+ VERSION = "0.1.4"
3
3
  end
@@ -3,15 +3,16 @@ module Xcselect
3
3
  require 'pathname'
4
4
  require 'json'
5
5
  require "plist"
6
+ require 'xcselect/nkissue'
6
7
 
7
8
  class XcApp
8
9
  include Comparable
9
10
  attr_reader :path
10
- attr_reader :plist
11
+ attr_reader :info_plist
11
12
 
12
13
  def initialize(path)
13
14
  @path = path
14
- @plist = JSON.parse read_plist(plist_path)
15
+ @info_plist = JSON.parse read_plist(plist_path)
15
16
  end
16
17
 
17
18
  def to_s
@@ -28,7 +29,7 @@ module Xcselect
28
29
  end
29
30
 
30
31
  def [](k)
31
- @plist[k]
32
+ @info_plist[k]
32
33
  end
33
34
 
34
35
  def base_dir
@@ -59,6 +60,10 @@ module Xcselect
59
60
  "#{base_dir}/Documents"
60
61
  end
61
62
 
63
+ def cache_path
64
+ "#{base_dir}/Library/Caches"
65
+ end
66
+
62
67
  def oomph_app?
63
68
  File.exists? "#{path}/Oomph.plist"
64
69
  end
@@ -67,36 +72,26 @@ module Xcselect
67
72
  self['UINewsstandApp'] || false
68
73
  end
69
74
 
75
+ # Returns a hash of NKIssues in the form {"issue_name" => path }
70
76
  def newsstand_objects
71
- issues = {}
77
+ issues = NKIssue.parse "#{base_dir}/Library/Application Support/com.apple.newsstand-library.plist"
78
+
72
79
  return issues unless newsstand?
73
- # this is an NSKeyedArchiver plist
74
- ns_plist = Plist::parse_xml(read_bin_plist_to_xml("#{base_dir}/Library/Application Support/com.apple.newsstand-library.plist"))
75
-
76
- # this is the integer that we will use to filter all archived nkissue objects
77
- nk_issue_key = ns_plist['$objects'].index(ns_plist['$objects'].select{|o| o['$classname'] == "NKIssue"}.last)
78
-
79
- # filter just the nkissue hashes
80
- obj_key_hashs = ns_plist['$objects'].select{|o| o.class == Hash && o['$class'] && nk_issue_key == o['$class']['CF$UID'] }
81
- object_array = ns_plist['$objects']
82
-
83
- # load these paths as our apps have 1 folder inside the newsstand folders
84
- paths = newsstand_issue_paths if oomph_app?
85
-
86
- obj_key_hashs.each do |nskey|
87
- name = object_array[nskey['name']['CF$UID']]
88
- uuid = object_array[nskey['directory']['CF$UID']]
89
- next if name.nil?
90
- issues[name] = "#{newsstand_path}/#{uuid}"
91
- issues[name] = paths.select{|p| p[uuid] }.last if oomph_app? # specially for me :)
80
+ paths = newsstand_issue_paths if oomph_app?
81
+ issues.values.each do |issue|
82
+ issue.content_path = "#{newsstand_path}/#{issue.uuid}"
83
+ issue.content_path = paths.select{|p| p[issue.uuid] }.last if oomph_app?
92
84
  end
85
+
93
86
  return issues
94
87
  end
95
88
 
89
+ # path to the app's root newsstand folder
96
90
  def newsstand_path
97
91
  "#{base_dir}/Library/Caches/Newsstand"
98
92
  end
99
93
 
94
+ # all directories in newsstand folder
100
95
  def newsstand_issue_paths
101
96
  #TODO: make this read the newsstand db and return a hash of names/paths
102
97
  if oomph_app?
@@ -105,19 +100,24 @@ module Xcselect
105
100
  Dir["#{newsstand_path}/*-*"]
106
101
  end
107
102
  end
108
-
103
+
109
104
  def last_build_time
110
105
  File.mtime path
111
106
  end
107
+
108
+ # Class methods
112
109
 
110
+ # the iPhone Simulator support folder
113
111
  def self.app_support_folder
114
112
  File.expand_path("~/Library/Application Support/iPhone Simulator/")
115
113
  end
116
114
 
115
+ # all applications for all simulator versions, unsorted
117
116
  def self.all_apps
118
117
  Dir["#{app_support_folder}/**/*.app"].map{|a| XcApp.new a }
119
118
  end
120
-
119
+
120
+ # every newsstand application
121
121
  def self.all_newsstand_apps
122
122
  self.all_apps.select(&:newsstand?)
123
123
  end
@@ -126,8 +126,12 @@ module Xcselect
126
126
  all_newsstand_apps.sort_by!{|e| e.last_build_time }.last
127
127
  end
128
128
 
129
+ def self.sort_by_touch_time array
130
+ array.sort_by{|e| e.last_build_time }
131
+ end
132
+
129
133
  def self.last_built_app
130
- XcApp.all_apps.sort_by!{|e| e.last_build_time }.last
134
+ XcApp.sort_by_touch_time(all_apps).last
131
135
  end
132
136
 
133
137
  end
@@ -33,7 +33,7 @@ class Xcode
33
33
  end
34
34
 
35
35
  def self.find_new_xcodes
36
- # Xcode in now in a single application, look for that and use that as a candidate
36
+ # Xcode is now in a single application, look for that and use that as a candidate
37
37
  newXcodes = `mdfind 'kMDItemCFBundleIdentifier = com.apple.dt.Xcode'`.chomp.split
38
38
  newXcodes = newXcodes.select do |x|
39
39
  File.exists? x + "/Contents/Developer/usr/bin/xcodebuild"
data/lib/xcselect.rb CHANGED
@@ -5,5 +5,6 @@ require "xcselect/xcode"
5
5
  require "xcselect/xcapp"
6
6
  require "xcselect/version"
7
7
  require "xcselect/dir_extension"
8
+ require "xcselect/nkissue"
8
9
 
9
10
  end
@@ -0,0 +1,407 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>$archiver</key>
6
+ <string>NSKeyedArchiver</string>
7
+ <key>$objects</key>
8
+ <array>
9
+ <string>$null</string>
10
+ <dict>
11
+ <key>$class</key>
12
+ <dict>
13
+ <key>CF$UID</key>
14
+ <integer>36</integer>
15
+ </dict>
16
+ <key>NS.keys</key>
17
+ <array>
18
+ <dict>
19
+ <key>CF$UID</key>
20
+ <integer>2</integer>
21
+ </dict>
22
+ </array>
23
+ <key>NS.objects</key>
24
+ <array>
25
+ <dict>
26
+ <key>CF$UID</key>
27
+ <integer>3</integer>
28
+ </dict>
29
+ </array>
30
+ </dict>
31
+ <string>issues</string>
32
+ <dict>
33
+ <key>$class</key>
34
+ <dict>
35
+ <key>CF$UID</key>
36
+ <integer>10</integer>
37
+ </dict>
38
+ <key>NS.objects</key>
39
+ <array>
40
+ <dict>
41
+ <key>CF$UID</key>
42
+ <integer>4</integer>
43
+ </dict>
44
+ <dict>
45
+ <key>CF$UID</key>
46
+ <integer>12</integer>
47
+ </dict>
48
+ <dict>
49
+ <key>CF$UID</key>
50
+ <integer>16</integer>
51
+ </dict>
52
+ <dict>
53
+ <key>CF$UID</key>
54
+ <integer>20</integer>
55
+ </dict>
56
+ <dict>
57
+ <key>CF$UID</key>
58
+ <integer>24</integer>
59
+ </dict>
60
+ <dict>
61
+ <key>CF$UID</key>
62
+ <integer>28</integer>
63
+ </dict>
64
+ <dict>
65
+ <key>CF$UID</key>
66
+ <integer>32</integer>
67
+ </dict>
68
+ </array>
69
+ </dict>
70
+ <dict>
71
+ <key>$class</key>
72
+ <dict>
73
+ <key>CF$UID</key>
74
+ <integer>11</integer>
75
+ </dict>
76
+ <key>assets</key>
77
+ <dict>
78
+ <key>CF$UID</key>
79
+ <integer>9</integer>
80
+ </dict>
81
+ <key>date</key>
82
+ <dict>
83
+ <key>CF$UID</key>
84
+ <integer>6</integer>
85
+ </dict>
86
+ <key>directory</key>
87
+ <dict>
88
+ <key>CF$UID</key>
89
+ <integer>8</integer>
90
+ </dict>
91
+ <key>foundContent</key>
92
+ <false/>
93
+ <key>name</key>
94
+ <dict>
95
+ <key>CF$UID</key>
96
+ <integer>5</integer>
97
+ </dict>
98
+ </dict>
99
+ <string>Lion</string>
100
+ <dict>
101
+ <key>$class</key>
102
+ <dict>
103
+ <key>CF$UID</key>
104
+ <integer>7</integer>
105
+ </dict>
106
+ <key>NS.time</key>
107
+ <real>332776800.000000</real>
108
+ </dict>
109
+ <dict>
110
+ <key>$classes</key>
111
+ <array>
112
+ <string>NSDate</string>
113
+ <string>NSObject</string>
114
+ </array>
115
+ <key>$classname</key>
116
+ <string>NSDate</string>
117
+ </dict>
118
+ <string>93EF18D7-BED2-4770-AE8B-46A5C406D7D3</string>
119
+ <dict>
120
+ <key>$class</key>
121
+ <dict>
122
+ <key>CF$UID</key>
123
+ <integer>10</integer>
124
+ </dict>
125
+ <key>NS.objects</key>
126
+ <array/>
127
+ </dict>
128
+ <dict>
129
+ <key>$classes</key>
130
+ <array>
131
+ <string>NSArray</string>
132
+ <string>NSObject</string>
133
+ </array>
134
+ <key>$classname</key>
135
+ <string>NSArray</string>
136
+ </dict>
137
+ <dict>
138
+ <key>$classes</key>
139
+ <array>
140
+ <string>NKIssue</string>
141
+ <string>NSObject</string>
142
+ </array>
143
+ <key>$classname</key>
144
+ <string>NKIssue</string>
145
+ </dict>
146
+ <dict>
147
+ <key>$class</key>
148
+ <dict>
149
+ <key>CF$UID</key>
150
+ <integer>11</integer>
151
+ </dict>
152
+ <key>assets</key>
153
+ <dict>
154
+ <key>CF$UID</key>
155
+ <integer>9</integer>
156
+ </dict>
157
+ <key>date</key>
158
+ <dict>
159
+ <key>CF$UID</key>
160
+ <integer>14</integer>
161
+ </dict>
162
+ <key>directory</key>
163
+ <dict>
164
+ <key>CF$UID</key>
165
+ <integer>15</integer>
166
+ </dict>
167
+ <key>foundContent</key>
168
+ <false/>
169
+ <key>name</key>
170
+ <dict>
171
+ <key>CF$UID</key>
172
+ <integer>13</integer>
173
+ </dict>
174
+ </dict>
175
+ <string>Mountain Lion</string>
176
+ <dict>
177
+ <key>$class</key>
178
+ <dict>
179
+ <key>CF$UID</key>
180
+ <integer>7</integer>
181
+ </dict>
182
+ <key>NS.time</key>
183
+ <real>364831200.000000</real>
184
+ </dict>
185
+ <string>8BA10DB9-0442-4CE1-8D06-10E0B5939DA7</string>
186
+ <dict>
187
+ <key>$class</key>
188
+ <dict>
189
+ <key>CF$UID</key>
190
+ <integer>11</integer>
191
+ </dict>
192
+ <key>assets</key>
193
+ <dict>
194
+ <key>CF$UID</key>
195
+ <integer>9</integer>
196
+ </dict>
197
+ <key>date</key>
198
+ <dict>
199
+ <key>CF$UID</key>
200
+ <integer>18</integer>
201
+ </dict>
202
+ <key>directory</key>
203
+ <dict>
204
+ <key>CF$UID</key>
205
+ <integer>19</integer>
206
+ </dict>
207
+ <key>foundContent</key>
208
+ <false/>
209
+ <key>name</key>
210
+ <dict>
211
+ <key>CF$UID</key>
212
+ <integer>17</integer>
213
+ </dict>
214
+ </dict>
215
+ <string>Snow Leopard</string>
216
+ <dict>
217
+ <key>$class</key>
218
+ <dict>
219
+ <key>CF$UID</key>
220
+ <integer>7</integer>
221
+ </dict>
222
+ <key>NS.time</key>
223
+ <real>273074400.000000</real>
224
+ </dict>
225
+ <string>846B96F1-E081-4120-A9E9-314ED21AB22C</string>
226
+ <dict>
227
+ <key>$class</key>
228
+ <dict>
229
+ <key>CF$UID</key>
230
+ <integer>11</integer>
231
+ </dict>
232
+ <key>assets</key>
233
+ <dict>
234
+ <key>CF$UID</key>
235
+ <integer>9</integer>
236
+ </dict>
237
+ <key>date</key>
238
+ <dict>
239
+ <key>CF$UID</key>
240
+ <integer>22</integer>
241
+ </dict>
242
+ <key>directory</key>
243
+ <dict>
244
+ <key>CF$UID</key>
245
+ <integer>23</integer>
246
+ </dict>
247
+ <key>foundContent</key>
248
+ <false/>
249
+ <key>name</key>
250
+ <dict>
251
+ <key>CF$UID</key>
252
+ <integer>21</integer>
253
+ </dict>
254
+ </dict>
255
+ <string>Leopard</string>
256
+ <dict>
257
+ <key>$class</key>
258
+ <dict>
259
+ <key>CF$UID</key>
260
+ <integer>7</integer>
261
+ </dict>
262
+ <key>NS.time</key>
263
+ <real>215013600.000000</real>
264
+ </dict>
265
+ <string>1874F72E-13FE-4B68-80D7-FB377AE5ACDA</string>
266
+ <dict>
267
+ <key>$class</key>
268
+ <dict>
269
+ <key>CF$UID</key>
270
+ <integer>11</integer>
271
+ </dict>
272
+ <key>assets</key>
273
+ <dict>
274
+ <key>CF$UID</key>
275
+ <integer>9</integer>
276
+ </dict>
277
+ <key>date</key>
278
+ <dict>
279
+ <key>CF$UID</key>
280
+ <integer>26</integer>
281
+ </dict>
282
+ <key>directory</key>
283
+ <dict>
284
+ <key>CF$UID</key>
285
+ <integer>27</integer>
286
+ </dict>
287
+ <key>foundContent</key>
288
+ <false/>
289
+ <key>name</key>
290
+ <dict>
291
+ <key>CF$UID</key>
292
+ <integer>25</integer>
293
+ </dict>
294
+ </dict>
295
+ <string>Tiger</string>
296
+ <dict>
297
+ <key>$class</key>
298
+ <dict>
299
+ <key>CF$UID</key>
300
+ <integer>7</integer>
301
+ </dict>
302
+ <key>NS.time</key>
303
+ <real>136389600.000000</real>
304
+ </dict>
305
+ <string>E1131C38-2719-490D-8D67-EFB1B6D08252</string>
306
+ <dict>
307
+ <key>$class</key>
308
+ <dict>
309
+ <key>CF$UID</key>
310
+ <integer>11</integer>
311
+ </dict>
312
+ <key>assets</key>
313
+ <dict>
314
+ <key>CF$UID</key>
315
+ <integer>9</integer>
316
+ </dict>
317
+ <key>date</key>
318
+ <dict>
319
+ <key>CF$UID</key>
320
+ <integer>30</integer>
321
+ </dict>
322
+ <key>directory</key>
323
+ <dict>
324
+ <key>CF$UID</key>
325
+ <integer>31</integer>
326
+ </dict>
327
+ <key>foundContent</key>
328
+ <false/>
329
+ <key>name</key>
330
+ <dict>
331
+ <key>CF$UID</key>
332
+ <integer>29</integer>
333
+ </dict>
334
+ </dict>
335
+ <string>Panther</string>
336
+ <dict>
337
+ <key>$class</key>
338
+ <dict>
339
+ <key>CF$UID</key>
340
+ <integer>7</integer>
341
+ </dict>
342
+ <key>NS.time</key>
343
+ <real>88610400.000000</real>
344
+ </dict>
345
+ <string>7C6268CD-B443-4417-96FC-B1CCFE5CA552</string>
346
+ <dict>
347
+ <key>$class</key>
348
+ <dict>
349
+ <key>CF$UID</key>
350
+ <integer>11</integer>
351
+ </dict>
352
+ <key>assets</key>
353
+ <dict>
354
+ <key>CF$UID</key>
355
+ <integer>9</integer>
356
+ </dict>
357
+ <key>date</key>
358
+ <dict>
359
+ <key>CF$UID</key>
360
+ <integer>34</integer>
361
+ </dict>
362
+ <key>directory</key>
363
+ <dict>
364
+ <key>CF$UID</key>
365
+ <integer>35</integer>
366
+ </dict>
367
+ <key>foundContent</key>
368
+ <false/>
369
+ <key>name</key>
370
+ <dict>
371
+ <key>CF$UID</key>
372
+ <integer>33</integer>
373
+ </dict>
374
+ </dict>
375
+ <string>Jaguar</string>
376
+ <dict>
377
+ <key>$class</key>
378
+ <dict>
379
+ <key>CF$UID</key>
380
+ <integer>7</integer>
381
+ </dict>
382
+ <key>NS.time</key>
383
+ <real>42300000.000000</real>
384
+ </dict>
385
+ <string>A98F7CDC-BE07-4C7D-80F2-F58E14D00CA9</string>
386
+ <dict>
387
+ <key>$classes</key>
388
+ <array>
389
+ <string>NSDictionary</string>
390
+ <string>NSObject</string>
391
+ </array>
392
+ <key>$classname</key>
393
+ <string>NSDictionary</string>
394
+ </dict>
395
+ </array>
396
+ <key>$top</key>
397
+ <dict>
398
+ <key>root</key>
399
+ <dict>
400
+ <key>CF$UID</key>
401
+ <integer>1</integer>
402
+ </dict>
403
+ </dict>
404
+ <key>$version</key>
405
+ <integer>100000</integer>
406
+ </dict>
407
+ </plist>
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
2
+
3
+ require "xcselect"
4
+ require "test/unit"
5
+ require "time"
6
+
7
+ include Xcselect
8
+
9
+
10
+ class NKIssueTest < Test::Unit::TestCase
11
+ attr_accessor :issues
12
+ def setup
13
+ @issues = NKIssue.parse "big_cats.plist"
14
+ end
15
+
16
+
17
+ def test_parser
18
+
19
+ versions = {"Panther" => "October 24, 2003",
20
+ "Tiger" => "April 29, 2005",
21
+ "Leopard" => "October 26, 2007",
22
+ "Snow Leopard" => "August 28, 2009",
23
+ "Lion" => "July 20, 2011",
24
+ "Mountain Lion" => "July 25, 2012",
25
+ "Jaguar" => "May 6, 2002" }
26
+ versions.each_key do |k|
27
+ nkissue = issues[k]
28
+ release_date = Time.strptime(versions[k], "%b %d, %Y")
29
+
30
+ # test correct date
31
+ assert_equal(nkissue.date, release_date)
32
+
33
+ # test uuid is set
34
+ assert(!nkissue.uuid.size.zero?)
35
+
36
+ assert_equal(7, issues.size)
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+
data/xcselect.gemspec CHANGED
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
7
7
  s.version = Xcselect::VERSION
8
8
  s.authors = ["Kim Hunter"]
9
9
  s.email = ["bigkm1@gmail.com"]
10
- s.homepage = ""
10
+ s.homepage = "https://github.com/bigkm/xcselect"
11
11
  s.summary = %q{xcselect - Xcode Select}
12
- s.description = %q{A more user friendly interface to the xcode-select command showing more info}
12
+ s.description = %q{A more user friendly interface to the xcode-select command showing more info, xcsim - access the simulator application folders quickly}
13
13
 
14
14
  s.rubyforge_project = "xcselect"
15
15
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcselect
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,10 +9,10 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-02 00:00:00.000000000 Z
12
+ date: 2012-08-05 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: A more user friendly interface to the xcode-select command showing more
15
- info
15
+ info, xcsim - access the simulator application folders quickly
16
16
  email:
17
17
  - bigkm1@gmail.com
18
18
  executables:
@@ -29,20 +29,15 @@ files:
29
29
  - bin/xcsim
30
30
  - lib/xcselect.rb
31
31
  - lib/xcselect/dir_extension.rb
32
+ - lib/xcselect/nkissue.rb
33
+ - lib/xcselect/string_colors.rb
32
34
  - lib/xcselect/version.rb
33
35
  - lib/xcselect/xcapp.rb
34
36
  - lib/xcselect/xcode.rb
35
- - pkg/xcselect-0.0.1.gem
36
- - pkg/xcselect-0.0.10.gem
37
- - pkg/xcselect-0.0.11.gem
38
- - pkg/xcselect-0.0.3.gem
39
- - pkg/xcselect-0.0.4.gem
40
- - pkg/xcselect-0.0.5.gem
41
- - pkg/xcselect-0.0.6.gem
42
- - pkg/xcselect-0.0.7.gem
43
- - pkg/xcselect-0.0.9.gem
37
+ - tests/big_cats.plist
38
+ - tests/test_nkissue.rb
44
39
  - xcselect.gemspec
45
- homepage: ''
40
+ homepage: https://github.com/bigkm/xcselect
46
41
  licenses: []
47
42
  post_install_message:
48
43
  rdoc_options: []
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file