pbind 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/pbind/command.rb +1 -4
- data/lib/pbind/command/mock.rb +29 -12
- data/lib/pbind/command/watch.rb +61 -9
- data/lib/pbind/user_interface.rb +23 -0
- data/source/PBLiveLoader/PBLiveLoader.m +50 -19
- metadata +2 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 573151dfdd2acf6d1bbc018dff4cbfc196827213
|
4
|
+
data.tar.gz: f66ce1b7a90dd88c069e533e75c3d429e06128ee
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d559bc9e5bf121749e96bc470f4c8f7b69dfdfbc2d39815da371456384b2a3e5e70ae3bb4fda47d112a5375549d0423ef0e7b66737ec8ea33e53f089878381cf
|
7
|
+
data.tar.gz: 845197b53f0976241409f41343dfab570d7fa50ea53c3cd7ca730f7651e5ad9c2b2a3d762c9ad1527c7dfc3bfc557018d6bf57bf9a7264d115868e2b6507eec1
|
data/lib/pbind/command.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require 'colored'
|
2
2
|
require 'claide'
|
3
3
|
|
4
|
-
require '
|
5
|
-
require 'cocoapods/user_interface'
|
4
|
+
require 'pbind/user_interface'
|
6
5
|
|
7
6
|
module Pbind
|
8
7
|
class Command < CLAide::Command
|
@@ -16,8 +15,6 @@ module Pbind
|
|
16
15
|
self.description = 'Pbind, the Pbind XcodeProject Helper.'
|
17
16
|
self.plugin_prefixes = %w(claide pbind)
|
18
17
|
|
19
|
-
UI = Pod::UI
|
20
|
-
|
21
18
|
def self.report_error(exception)
|
22
19
|
case exception
|
23
20
|
when Interrupt
|
data/lib/pbind/command/mock.rb
CHANGED
@@ -27,6 +27,7 @@ module Pbind
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def run
|
30
|
+
@action = @action.gsub(/\//, '-')
|
30
31
|
@api_name = 'PBLocalhost'
|
31
32
|
@project_root = File.dirname(@project_path)
|
32
33
|
@api_install_dir = File.absolute_path(File.join(@project_root, @api_name))
|
@@ -57,14 +58,16 @@ module Pbind
|
|
57
58
|
group = project.main_group.find_subpath(@api_name, true)
|
58
59
|
if group.empty?
|
59
60
|
group.clear
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
61
|
+
UI.section("Create group \"PBLocalhost\"") do
|
62
|
+
file_refs = Array.new
|
63
|
+
Dir.foreach(@api_install_dir) do |file|
|
64
|
+
if !File.directory?(file)
|
65
|
+
file_refs << group.new_reference(File.join(@api_install_dir, file))
|
66
|
+
end
|
64
67
|
end
|
68
|
+
target.add_file_references(file_refs)
|
69
|
+
changed = true
|
65
70
|
end
|
66
|
-
target.add_file_references(file_refs)
|
67
|
-
changed = true
|
68
71
|
end
|
69
72
|
|
70
73
|
# Create directory
|
@@ -75,29 +78,43 @@ module Pbind
|
|
75
78
|
end
|
76
79
|
|
77
80
|
# Create json file
|
78
|
-
|
81
|
+
json_name = "#{@action}.json"
|
82
|
+
json_path = File.join(client_dir, json_name)
|
83
|
+
json_relative_path = "PBLocalhost/#{@client}/#{json_name}"
|
79
84
|
if !File.exists?(json_path)
|
80
|
-
|
81
|
-
|
82
|
-
|
85
|
+
UI.section("Creating file `#{json_name}`") do
|
86
|
+
json_file = File.new(json_path, 'w')
|
87
|
+
json_file.print("{\n \n}")
|
88
|
+
changed = true
|
89
|
+
end
|
83
90
|
end
|
84
91
|
|
85
92
|
# Add json file reference
|
86
93
|
group = group.find_subpath(@client, true)
|
94
|
+
added = true
|
87
95
|
if group.empty?
|
88
96
|
group.clear
|
97
|
+
added = false
|
98
|
+
else
|
99
|
+
found = group.files.index {|x| x.path==json_relative_path}
|
100
|
+
if found == nil
|
101
|
+
added = false
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
if !added
|
89
106
|
file_refs = Array.new
|
90
107
|
file_refs << group.new_reference(json_path)
|
91
108
|
target.add_file_references(file_refs)
|
92
109
|
changed = true
|
93
110
|
end
|
94
111
|
|
95
|
-
# Save
|
96
112
|
if !changed
|
97
113
|
return
|
98
114
|
end
|
99
115
|
|
100
|
-
|
116
|
+
# Save
|
117
|
+
UI.section("Adding reference `#{json_name}`") do
|
101
118
|
project.save
|
102
119
|
@changed = true
|
103
120
|
end
|
data/lib/pbind/command/watch.rb
CHANGED
@@ -53,15 +53,67 @@ module Pbind
|
|
53
53
|
# @return [void]
|
54
54
|
#
|
55
55
|
def install_sources
|
56
|
-
|
57
|
-
|
56
|
+
source_dir = ENV['PBIND_SOURCE']
|
57
|
+
src_dir = File.join(source_dir, @src_name)
|
58
|
+
|
59
|
+
if !File.exists?(@src_install_dir)
|
60
|
+
UI.section("Copying `#{@src_name}` into `#{@project_root}`") do
|
61
|
+
FileUtils.cp_r src_dir, @project_root
|
62
|
+
@changed = true
|
63
|
+
end
|
64
|
+
else
|
65
|
+
# Check for upgrade.
|
66
|
+
Dir.foreach(@src_install_dir) do |filename|
|
67
|
+
if File.directory?(filename)
|
68
|
+
next
|
69
|
+
end
|
70
|
+
|
71
|
+
src_file = File.join(src_dir, filename)
|
72
|
+
if !File.exists?(src_file)
|
73
|
+
next
|
74
|
+
end
|
75
|
+
|
76
|
+
dst_file = File.join(@src_install_dir, filename)
|
77
|
+
src_md5 = Digest::MD5.hexdigest( File.open(src_file, "rb"){|fs| fs.read} )
|
78
|
+
dst_md5 = Digest::MD5.hexdigest( File.open(dst_file, "rb"){|fs| fs.read} )
|
79
|
+
if src_md5 != dst_md5
|
80
|
+
UI.section("Upgrading `#{@src_name}/#{filename}`") do
|
81
|
+
FileUtils.cp src_file, dst_file
|
82
|
+
@changed = true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
58
86
|
end
|
59
87
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
88
|
+
src_dir = File.join(source_dir, @api_name)
|
89
|
+
|
90
|
+
if !File.exists?(@api_install_dir)
|
91
|
+
UI.section("Copying `#{@api_name}` into `#{@project_root}`") do
|
92
|
+
FileUtils.cp_r src_dir, @project_root
|
93
|
+
@changed = true
|
94
|
+
end
|
95
|
+
else
|
96
|
+
# Check for upgrade.
|
97
|
+
Dir.foreach(@api_install_dir) do |filename|
|
98
|
+
if File.directory?(filename)
|
99
|
+
next
|
100
|
+
end
|
101
|
+
|
102
|
+
src_file = File.join(src_dir, filename)
|
103
|
+
if !File.exists?(src_file)
|
104
|
+
next
|
105
|
+
end
|
106
|
+
|
107
|
+
dst_file = File.join(@api_install_dir, filename)
|
108
|
+
src_md5 = Digest::MD5.hexdigest(File.open(src_file, "rb"){|fs| fs.read} )
|
109
|
+
dst_md5 = Digest::MD5.hexdigest(File.open(dst_file, "rb"){|fs| fs.read} )
|
110
|
+
if src_md5 != dst_md5
|
111
|
+
UI.section("Upgrading `#{@api_name}/#{filename}`") do
|
112
|
+
FileUtils.cp src_file, dst_file
|
113
|
+
@changed = true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
65
117
|
end
|
66
118
|
end
|
67
119
|
|
@@ -100,7 +152,7 @@ module Pbind
|
|
100
152
|
return
|
101
153
|
end
|
102
154
|
|
103
|
-
UI.section("
|
155
|
+
UI.section("Adding plist entires to `#{@project_path}`") do
|
104
156
|
Xcodeproj::Plist.write_to_path(plist, info_plist_path)
|
105
157
|
@changed = true
|
106
158
|
end
|
@@ -148,7 +200,7 @@ module Pbind
|
|
148
200
|
return
|
149
201
|
end
|
150
202
|
|
151
|
-
UI.section("
|
203
|
+
UI.section("Adding group references to `#{@project_path}`") do
|
152
204
|
project.save
|
153
205
|
@changed = true
|
154
206
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Pbind
|
2
|
+
module UI
|
3
|
+
|
4
|
+
require "colored"
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
def section(title)
|
9
|
+
message = "%-64s" % title
|
10
|
+
print message.yellow
|
11
|
+
|
12
|
+
yield if block_given?
|
13
|
+
|
14
|
+
puts '[ OK ]'.green
|
15
|
+
end
|
16
|
+
|
17
|
+
def notice(message)
|
18
|
+
puts ''
|
19
|
+
puts "[!] #{message}".green
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -14,9 +14,12 @@
|
|
14
14
|
|
15
15
|
@implementation PBLiveLoader
|
16
16
|
|
17
|
-
static NSString *const
|
18
|
-
static NSString *const
|
19
|
-
static NSString *const
|
17
|
+
static NSString *const kPlistSuffix = @".plist";
|
18
|
+
static NSString *const kJSONSuffix = @".json";
|
19
|
+
static NSString *const kIgnoresFile = @"ignore.h";
|
20
|
+
|
21
|
+
static NSString *const kDebugJSONRedirectKey = @"$redirect";
|
22
|
+
static NSString *const kDebugJSONStatusKey = @"$status";
|
20
23
|
|
21
24
|
static NSArray<NSString *> *kIgnoreAPIs;
|
22
25
|
static PBDirectoryWatcher *kResWatcher;
|
@@ -45,12 +48,12 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
45
48
|
+ (void)watchPlist {
|
46
49
|
NSString *resPath = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"PBResourcesPath"];
|
47
50
|
if (resPath == nil) {
|
48
|
-
NSLog(@"
|
51
|
+
NSLog(@"PBLiveLoader: Please define PBResourcesPath in Info.plist with value '$(SRCROOT)/[path-to-resources]'!");
|
49
52
|
return;
|
50
53
|
}
|
51
54
|
|
52
55
|
if (![[NSFileManager defaultManager] fileExistsAtPath:resPath]) {
|
53
|
-
NSLog(@"
|
56
|
+
NSLog(@"PBLiveLoader: PBResourcesPath is not exists! (%@)", resPath);
|
54
57
|
return;
|
55
58
|
}
|
56
59
|
|
@@ -58,20 +61,20 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
58
61
|
[kResWatcher watchDir:resPath handler:^(NSString *path, BOOL initial, PBDirEvent event) {
|
59
62
|
switch (event) {
|
60
63
|
case PBDirEventNewFile:
|
61
|
-
if (HasSuffix(path,
|
64
|
+
if (HasSuffix(path, kPlistSuffix)) {
|
62
65
|
NSBundle *updatedBundle = [NSBundle bundleWithPath:[path stringByDeletingLastPathComponent]];
|
63
66
|
[Pbind addResourcesBundle:updatedBundle];
|
64
67
|
}
|
65
68
|
break;
|
66
69
|
|
67
70
|
case PBDirEventModifyFile:
|
68
|
-
if (HasSuffix(path,
|
71
|
+
if (HasSuffix(path, kPlistSuffix)) {
|
69
72
|
[Pbind reloadViewsOnPlistUpdate:path];
|
70
73
|
}
|
71
74
|
break;
|
72
75
|
|
73
76
|
case PBDirEventDeleteFile:
|
74
|
-
if (HasSuffix(path,
|
77
|
+
if (HasSuffix(path, kPlistSuffix)) {
|
75
78
|
[Pbind reloadViewsOnPlistUpdate:path];
|
76
79
|
}
|
77
80
|
break;
|
@@ -85,12 +88,12 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
85
88
|
+ (void)watchAPI {
|
86
89
|
NSString *serverPath = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"PBLocalhost"];
|
87
90
|
if (serverPath == nil) {
|
88
|
-
NSLog(@"
|
91
|
+
NSLog(@"PBLiveLoader: Please define PBLocalhost in Info.plist with value '$(SRCROOT)/[path-to-api]'!");
|
89
92
|
return;
|
90
93
|
}
|
91
94
|
|
92
95
|
if (![[NSFileManager defaultManager] fileExistsAtPath:serverPath]) {
|
93
|
-
NSLog(@"
|
96
|
+
NSLog(@"PBLiveLoader: PBLocalhost is not exists! (%@)", serverPath);
|
94
97
|
return;
|
95
98
|
}
|
96
99
|
|
@@ -98,23 +101,23 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
98
101
|
[kAPIWatcher watchDir:serverPath handler:^(NSString *path, BOOL initial, PBDirEvent event) {
|
99
102
|
switch (event) {
|
100
103
|
case PBDirEventNewFile:
|
101
|
-
if (HasSuffix(path,
|
104
|
+
if (HasSuffix(path, kIgnoresFile)) {
|
102
105
|
kIgnoreAPIs = [self ignoreAPIsWithContentsOfFile:path];
|
103
106
|
}
|
104
107
|
break;
|
105
108
|
|
106
109
|
case PBDirEventModifyFile:
|
107
|
-
if (HasSuffix(path,
|
110
|
+
if (HasSuffix(path, kJSONSuffix)) {
|
108
111
|
[self reloadViewsOnJSONChange:path deleted:NO];
|
109
|
-
} else if (HasSuffix(path,
|
112
|
+
} else if (HasSuffix(path, kIgnoresFile)) {
|
110
113
|
[self reloadViewsOnIgnoresChange:path deleted:NO];
|
111
114
|
}
|
112
115
|
break;
|
113
116
|
|
114
117
|
case PBDirEventDeleteFile:
|
115
|
-
if (HasSuffix(path,
|
118
|
+
if (HasSuffix(path, kJSONSuffix)) {
|
116
119
|
[self reloadViewsOnJSONChange:path deleted:YES];
|
117
|
-
} else if (HasSuffix(path,
|
120
|
+
} else if (HasSuffix(path, kIgnoresFile)) {
|
118
121
|
[self reloadViewsOnIgnoresChange:path deleted:YES];
|
119
122
|
}
|
120
123
|
break;
|
@@ -130,6 +133,11 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
130
133
|
action = [action substringFromIndex:1]; // bypass '/'
|
131
134
|
}
|
132
135
|
|
136
|
+
NSString *method = request.method;
|
137
|
+
if (method != nil && ![method isEqualToString:@"GET"]) {
|
138
|
+
action = [action stringByAppendingFormat:@"@%@", [method lowercaseString]];
|
139
|
+
}
|
140
|
+
action = [action stringByReplacingOccurrencesOfString:@"/" withString:@"-"];
|
133
141
|
if (kIgnoreAPIs != nil && [kIgnoreAPIs containsObject:action]) {
|
134
142
|
return nil;
|
135
143
|
}
|
@@ -137,17 +145,41 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
137
145
|
NSString *jsonName = [NSString stringWithFormat:@"%@/%@.json", [[client class] description], action];
|
138
146
|
NSString *jsonPath = [serverPath stringByAppendingPathComponent:jsonName];
|
139
147
|
if (![[NSFileManager defaultManager] fileExistsAtPath:jsonPath]) {
|
140
|
-
NSLog(@"
|
148
|
+
NSLog(@"PBLiveLoader: Missing '%@', ignores!", jsonName);
|
141
149
|
return nil;
|
142
150
|
}
|
143
151
|
NSData *jsonData = [NSData dataWithContentsOfFile:jsonPath];
|
144
152
|
NSError *error = nil;
|
145
|
-
|
153
|
+
|
154
|
+
PBResponse *response = [[PBResponse alloc] init];
|
155
|
+
response.data = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
|
146
156
|
if (error != nil) {
|
147
|
-
NSLog(@"
|
157
|
+
NSLog(@"PBLiveLoader: Invalid '%@', ignores! The file format should be pure JSON style.", jsonName);
|
148
158
|
return nil;
|
149
159
|
}
|
150
160
|
|
161
|
+
if ([response.data isKindOfClass:[NSDictionary class]]) {
|
162
|
+
NSString *redirect = [response.data objectForKey:kDebugJSONRedirectKey];
|
163
|
+
if (redirect != nil) {
|
164
|
+
PBExpression *expression = [PBExpression expressionWithString:redirect];
|
165
|
+
if (expression != nil) {
|
166
|
+
response.data = [expression valueWithData:nil];
|
167
|
+
}
|
168
|
+
} else {
|
169
|
+
NSString *statusString = [response.data objectForKey:kDebugJSONStatusKey];
|
170
|
+
if (statusString != nil) {
|
171
|
+
response.status = [statusString intValue];
|
172
|
+
}
|
173
|
+
NSMutableDictionary *filteredDict = [NSMutableDictionary dictionaryWithDictionary:response.data];
|
174
|
+
[filteredDict removeObjectForKey:kDebugJSONStatusKey];
|
175
|
+
if (filteredDict.count == 0) {
|
176
|
+
response.data = nil;
|
177
|
+
} else {
|
178
|
+
response.data = filteredDict;
|
179
|
+
}
|
180
|
+
}
|
181
|
+
}
|
182
|
+
|
151
183
|
return response;
|
152
184
|
}];
|
153
185
|
}
|
@@ -181,7 +213,6 @@ static BOOL HasSuffix(NSString *src, NSString *tail)
|
|
181
213
|
}
|
182
214
|
|
183
215
|
NSArray *changedIgnores;
|
184
|
-
|
185
216
|
if (oldIgnores != nil) {
|
186
217
|
NSArray *deletedIgnores = [oldIgnores filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT SELF IN %@", newIgnores]];
|
187
218
|
NSArray *addedIgnores = [newIgnores filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"NOT SELF IN %@", oldIgnores]];
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pbind
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Galen Lin
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- lib/pbind/command.rb
|
63
63
|
- lib/pbind/command/mock.rb
|
64
64
|
- lib/pbind/command/watch.rb
|
65
|
+
- lib/pbind/user_interface.rb
|
65
66
|
- source/PBLiveLoader/PBDirectoryWatcher.h
|
66
67
|
- source/PBLiveLoader/PBDirectoryWatcher.m
|
67
68
|
- source/PBLiveLoader/PBLiveLoader.h
|