xcselect 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +2 -1
- data/README.md +34 -2
- data/bin/xcselect +1 -1
- data/bin/xcsim +97 -2
- data/lib/xcselect.rb +1 -0
- data/lib/xcselect/version.rb +1 -1
- data/lib/xcselect/xcapp.rb +124 -0
- metadata +25 -41
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
Basic usage
|
2
2
|
|
3
3
|
$ xcselect
|
4
|
-
Please Select an Xcode
|
4
|
+
Please Select an Xcode ?
|
5
5
|
|
6
6
|
[1] Xcode 4.1 (4B110) /Developer
|
7
|
-
[2] Xcode 4.2 (4D5163b) /Xcode42
|
7
|
+
[2] Xcode 4.2 (4D5163b) /Xcode42
|
8
|
+
[3] Xcode 4.4 (4F250) [current]
|
8
9
|
|
9
10
|
Selection:
|
10
11
|
|
@@ -20,3 +21,34 @@ Use show -s to print info about the current xcode
|
|
20
21
|
To open the current xcode (but will open first .xcproject in working dir if exists)
|
21
22
|
|
22
23
|
xcselect -o
|
24
|
+
|
25
|
+
|
26
|
+
I use this in my bash profile to open an xcode project
|
27
|
+
alias ox="xcselect -o"
|
28
|
+
|
29
|
+
|
30
|
+
xcsim command
|
31
|
+
-------------
|
32
|
+
|
33
|
+
xcsim command is a helper for opening particular directories in apps in the simulator support folder. It has support for opening newsstand issues. Most of its commands are based on app that was last built.
|
34
|
+
|
35
|
+
for help
|
36
|
+
|
37
|
+
$ xcsim -h
|
38
|
+
|
39
|
+
Show a list of apps, make a selection to open in finder
|
40
|
+
|
41
|
+
$ xcsim -a
|
42
|
+
|
43
|
+
Show all newsstand issues for last built app, and select to open in finder
|
44
|
+
|
45
|
+
$ xcsim -n
|
46
|
+
|
47
|
+
Open documents folder for last built app
|
48
|
+
|
49
|
+
$ xcsim -d
|
50
|
+
|
51
|
+
|
52
|
+
Add -p before any of these and xcsim will print the path.
|
53
|
+
|
54
|
+
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
data/bin/xcsim
CHANGED
@@ -2,12 +2,107 @@
|
|
2
2
|
|
3
3
|
$LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
|
4
4
|
|
5
|
-
require "fileutils"
|
6
5
|
require 'xcselect'
|
6
|
+
require "fileutils"
|
7
|
+
require "optparse"
|
7
8
|
|
8
9
|
include Xcselect
|
10
|
+
class Main
|
11
|
+
attr_reader :exit_code
|
12
|
+
def initialize
|
13
|
+
@options = default_options
|
14
|
+
@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
|
+
opts.on('-p', '--print', "print the path instead of opening it") { @options[:print] = true }
|
19
|
+
opts.on('-d', '--latest-documents' , "Reveal last built app's documents folder") { show_latest_docs() ;exit}
|
20
|
+
opts.on('-n', '--latest-newsstand' , "Show list of newsstand issues for last built app") { show_latest_newsstand(); exit }
|
21
|
+
opts.on('-a', '--apps' , "Show list of apps") { show_apps(); exit }
|
22
|
+
end
|
23
|
+
begin
|
24
|
+
optparse.parse!
|
25
|
+
rescue OptionParser::InvalidOption => e
|
26
|
+
puts "Invalid Option"
|
27
|
+
puts optparse
|
28
|
+
exit 2
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def default_options
|
33
|
+
{:print => false}
|
34
|
+
end
|
35
|
+
|
36
|
+
def open_path p
|
37
|
+
if @options[:print]
|
38
|
+
puts p
|
39
|
+
else
|
40
|
+
`open -R "#{p}"`
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def select_menu title, selections
|
45
|
+
i = 0
|
46
|
+
puts title
|
47
|
+
selections.each do |opt|
|
48
|
+
i += 1
|
49
|
+
puts " [#{i}] #{opt}"
|
50
|
+
end
|
51
|
+
print "\nSelection: "
|
52
|
+
begin
|
53
|
+
return unless STDIN.tty?
|
54
|
+
input = STDIN.gets
|
55
|
+
input = input.to_i
|
56
|
+
if input.zero? or input > selections.size
|
57
|
+
puts "Invalid Selection"
|
58
|
+
@exit_code = 1
|
59
|
+
else
|
60
|
+
yield input - 1
|
61
|
+
end
|
62
|
+
rescue SystemExit, Interrupt
|
63
|
+
puts ""
|
64
|
+
end
|
65
|
+
return -1
|
66
|
+
end
|
9
67
|
|
68
|
+
# ============
|
69
|
+
# = Commands =
|
70
|
+
# ============
|
71
|
+
def show_latest_newsstand
|
72
|
+
latest_app = XcApp.last_built_newsstand_app
|
73
|
+
ns_issues = latest_app.newsstand_objects
|
74
|
+
issue_paths = latest_app.newsstand_issue_paths
|
75
|
+
issue_names = ns_issues.keys
|
76
|
+
if issue_names.size == 1
|
77
|
+
puts "opening only issue #{issue_names.last}" unless @options[:print]
|
78
|
+
open_path ns_issues.last[issue_names.last]
|
79
|
+
return
|
80
|
+
end
|
81
|
+
select_menu("Select issue in #{latest_app.name} to open:", issue_names) {|i|
|
82
|
+
open_path ns_issues.values[i]
|
83
|
+
}
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
def show_latest_docs
|
88
|
+
app = XcApp.last_built_app
|
89
|
+
open_path app.documents_path
|
90
|
+
end
|
91
|
+
|
92
|
+
def show_apps
|
93
|
+
apps = XcApp.all_apps.sort
|
94
|
+
return @exit_code = 1 if apps.size == 0
|
95
|
+
if apps.size == 1
|
96
|
+
puts "opening only app #{apps}" unless @options[:print]
|
97
|
+
open_path issue_paths.last
|
98
|
+
end
|
99
|
+
select_menu("Select an app to open:", apps.map(&:to_s)) do |selected_index|
|
100
|
+
open_path(apps[selected_index].base_dir)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
10
104
|
|
11
105
|
|
106
|
+
main = Main.new
|
107
|
+
exit main.exit_code
|
12
108
|
|
13
|
-
puts XcSimulator.get_sims
|
data/lib/xcselect.rb
CHANGED
data/lib/xcselect/version.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
|
2
|
+
module Xcselect
|
3
|
+
require 'pathname'
|
4
|
+
require 'json'
|
5
|
+
require "plist"
|
6
|
+
|
7
|
+
class XcApp
|
8
|
+
include Comparable
|
9
|
+
attr_reader :path
|
10
|
+
attr_reader :plist
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
@plist = JSON.parse read_plist(plist_path)
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_s
|
18
|
+
"#{name} (#{sim_version})"
|
19
|
+
end
|
20
|
+
|
21
|
+
def <=>(o)
|
22
|
+
result = sim_version.to_f <=> o.sim_version.to_f
|
23
|
+
(!result.zero?) ? result : name <=> o.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def sim_version
|
27
|
+
path.split('/')[-4]
|
28
|
+
end
|
29
|
+
|
30
|
+
def [](k)
|
31
|
+
@plist[k]
|
32
|
+
end
|
33
|
+
|
34
|
+
def base_dir
|
35
|
+
File.dirname path
|
36
|
+
end
|
37
|
+
|
38
|
+
def bundle_id
|
39
|
+
self['CFBundleIdentifier']
|
40
|
+
end
|
41
|
+
|
42
|
+
def name
|
43
|
+
self['CFBundleName']
|
44
|
+
end
|
45
|
+
|
46
|
+
def read_plist plist_path
|
47
|
+
`plutil -convert json -o - '#{plist_path}'`
|
48
|
+
end
|
49
|
+
|
50
|
+
def read_bin_plist_to_xml plist_path
|
51
|
+
`plutil -convert xml1 -o - '#{plist_path}'`
|
52
|
+
end
|
53
|
+
|
54
|
+
def plist_path
|
55
|
+
Dir[@path + "/*Info.plist"].first
|
56
|
+
end
|
57
|
+
|
58
|
+
def documents_path
|
59
|
+
"#{base_dir}/Documents"
|
60
|
+
end
|
61
|
+
|
62
|
+
def oomph_app?
|
63
|
+
File.exists? "#{path}/Oomph.plist"
|
64
|
+
end
|
65
|
+
|
66
|
+
def newsstand?
|
67
|
+
self['UINewsstandApp'] || false
|
68
|
+
end
|
69
|
+
|
70
|
+
def newsstand_objects
|
71
|
+
ppath = "#{base_dir}/Library/Application Support/com.apple.newsstand-library.plist"
|
72
|
+
ns_plist = Plist::parse_xml(read_bin_plist_to_xml(ppath))
|
73
|
+
items = ns_plist['$objects'].select{|o| o.class == String && ["$null","issues"].index(o).nil? }
|
74
|
+
hash = {}
|
75
|
+
paths = newsstand_issue_paths
|
76
|
+
items.each_slice(2) {|name,uuid|
|
77
|
+
uuid = newsstand_path if uuid.nil?
|
78
|
+
hash[name] = paths.select{|p| p[uuid] }.last
|
79
|
+
hash[name] = File.dirname hash[name] unless oomph_app?
|
80
|
+
}
|
81
|
+
return hash
|
82
|
+
end
|
83
|
+
|
84
|
+
def newsstand_path
|
85
|
+
"#{base_dir}/Library/Caches/Newsstand"
|
86
|
+
end
|
87
|
+
|
88
|
+
def newsstand_issue_paths
|
89
|
+
#TODO: make this read the newsstand db and return a hash of names/paths
|
90
|
+
if oomph_app?
|
91
|
+
Dir["#{newsstand_path}/*-*/*"]
|
92
|
+
else
|
93
|
+
Dir["#{newsstand_path}/*-*"]
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def last_build_time
|
98
|
+
File.mtime path
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.app_support_folder
|
102
|
+
File.expand_path("~/Library/Application Support/iPhone Simulator/")
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.all_apps
|
106
|
+
Dir["#{app_support_folder}/**/*.app"].map{|a| XcApp.new a }
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.all_newsstand_apps
|
110
|
+
self.all_apps.select(&:newsstand?)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.last_built_newsstand_app
|
114
|
+
all_newsstand_apps.sort_by!{|e| e.last_build_time }.last
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.last_built_app
|
118
|
+
XcApp.all_apps.sort_by!{|e| e.last_build_time }.last
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
end
|
metadata
CHANGED
@@ -1,34 +1,26 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: xcselect
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 1
|
8
|
-
- 1
|
9
|
-
version: 0.1.1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
prerelease:
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Kim Hunter
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
date: 2012-07-18 00:00:00 +10:00
|
18
|
-
default_executable:
|
12
|
+
date: 2012-08-02 00:00:00.000000000 Z
|
19
13
|
dependencies: []
|
20
|
-
|
21
|
-
|
22
|
-
email:
|
14
|
+
description: A more user friendly interface to the xcode-select command showing more
|
15
|
+
info
|
16
|
+
email:
|
23
17
|
- bigkm1@gmail.com
|
24
|
-
executables:
|
18
|
+
executables:
|
25
19
|
- xcselect
|
26
20
|
- xcsim
|
27
21
|
extensions: []
|
28
|
-
|
29
22
|
extra_rdoc_files: []
|
30
|
-
|
31
|
-
files:
|
23
|
+
files:
|
32
24
|
- .gitignore
|
33
25
|
- Gemfile
|
34
26
|
- README.md
|
@@ -38,6 +30,7 @@ files:
|
|
38
30
|
- lib/xcselect.rb
|
39
31
|
- lib/xcselect/dir_extension.rb
|
40
32
|
- lib/xcselect/version.rb
|
33
|
+
- lib/xcselect/xcapp.rb
|
41
34
|
- lib/xcselect/xcode.rb
|
42
35
|
- pkg/xcselect-0.0.1.gem
|
43
36
|
- pkg/xcselect-0.0.10.gem
|
@@ -49,37 +42,28 @@ files:
|
|
49
42
|
- pkg/xcselect-0.0.7.gem
|
50
43
|
- pkg/xcselect-0.0.9.gem
|
51
44
|
- xcselect.gemspec
|
52
|
-
|
53
|
-
homepage: ""
|
45
|
+
homepage: ''
|
54
46
|
licenses: []
|
55
|
-
|
56
47
|
post_install_message:
|
57
48
|
rdoc_options: []
|
58
|
-
|
59
|
-
require_paths:
|
49
|
+
require_paths:
|
60
50
|
- lib
|
61
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
51
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
52
|
none: false
|
63
|
-
requirements:
|
64
|
-
- -
|
65
|
-
- !ruby/object:Gem::Version
|
66
|
-
|
67
|
-
|
68
|
-
version: "0"
|
69
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
53
|
+
requirements:
|
54
|
+
- - ! '>='
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: '0'
|
57
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
58
|
none: false
|
71
|
-
requirements:
|
72
|
-
- -
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
|
75
|
-
- 0
|
76
|
-
version: "0"
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
77
63
|
requirements: []
|
78
|
-
|
79
64
|
rubyforge_project: xcselect
|
80
|
-
rubygems_version: 1.
|
65
|
+
rubygems_version: 1.8.24
|
81
66
|
signing_key:
|
82
67
|
specification_version: 3
|
83
68
|
summary: xcselect - Xcode Select
|
84
69
|
test_files: []
|
85
|
-
|