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 +1 -0
- data/README.md +3 -0
- data/bin/xcselect +1 -20
- data/bin/xcsim +79 -22
- data/lib/xcselect/nkissue.rb +55 -0
- data/lib/xcselect/string_colors.rb +19 -0
- data/lib/xcselect/version.rb +1 -1
- data/lib/xcselect/xcapp.rb +30 -26
- data/lib/xcselect/xcode.rb +1 -1
- data/lib/xcselect.rb +1 -0
- data/tests/big_cats.plist +407 -0
- data/tests/test_nkissue.rb +43 -0
- data/xcselect.gemspec +2 -2
- metadata +8 -13
- data/pkg/xcselect-0.0.1.gem +0 -0
- data/pkg/xcselect-0.0.10.gem +0 -0
- data/pkg/xcselect-0.0.11.gem +0 -0
- data/pkg/xcselect-0.0.3.gem +0 -0
- data/pkg/xcselect-0.0.4.gem +0 -0
- data/pkg/xcselect-0.0.5.gem +0 -0
- data/pkg/xcselect-0.0.6.gem +0 -0
- data/pkg/xcselect-0.0.7.gem +0 -0
- data/pkg/xcselect-0.0.9.gem +0 -0
data/.gitignore
CHANGED
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('-
|
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
|
-
|
23
|
-
opts.on('-
|
24
|
-
opts.on('-
|
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
|
-
|
71
|
+
`open -R "#{p}"`
|
49
72
|
end
|
50
73
|
end
|
51
74
|
|
75
|
+
|
52
76
|
def select_menu title, selections
|
53
|
-
|
54
|
-
|
55
|
-
|
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
|
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
|
-
|
109
|
-
|
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
|
data/lib/xcselect/version.rb
CHANGED
data/lib/xcselect/xcapp.rb
CHANGED
@@ -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 :
|
11
|
+
attr_reader :info_plist
|
11
12
|
|
12
13
|
def initialize(path)
|
13
14
|
@path = path
|
14
|
-
@
|
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
|
-
@
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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.
|
134
|
+
XcApp.sort_by_touch_time(all_apps).last
|
131
135
|
end
|
132
136
|
|
133
137
|
end
|
data/lib/xcselect/xcode.rb
CHANGED
@@ -33,7 +33,7 @@ class Xcode
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.find_new_xcodes
|
36
|
-
# Xcode
|
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
@@ -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.
|
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-
|
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
|
-
-
|
36
|
-
-
|
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: []
|
data/pkg/xcselect-0.0.1.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.10.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.11.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.3.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.4.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.5.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.6.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.7.gem
DELETED
Binary file
|
data/pkg/xcselect-0.0.9.gem
DELETED
Binary file
|