hotreload 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c06e1f69e44e90bdb80283e3d314cedf32b43e1c
4
+ data.tar.gz: 71b80d3601f4fb729d2d8b73c30a6d445bfc605d
5
+ SHA512:
6
+ metadata.gz: c7d524e36dd65e25eb4ef488225bfc86c8a05b64f485194d000ffd4f73f5f17db8072993c4954953fe1ecfd9e8f1e5bf141f0d8152c9a1ae34de5f291b776686
7
+ data.tar.gz: 5ad1d92fafe72204fcb20ce1c4030f4f858795d814e251b11d5f99162b4a6ec75215945adb8696c4d0d501b3507622ef4ea918253068293d0d16eb68a5277747
data/bin/hotreload ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'hotreload'
4
+
5
+ HotReload.new.startServer(ARGV[0])
data/lib/config.rb ADDED
@@ -0,0 +1,27 @@
1
+ module Config
2
+ PORT = 8898
3
+ HOST = '127.0.0.1'
4
+ CLIENT_NUM = 1
5
+ HOTRELOAD_KEY = 'bvijkijyhbt73jdk83ljbbzcfbbvvq'
6
+ end
7
+
8
+ # Command
9
+ module Command
10
+ # responses from client
11
+ InjectionComplete = 0
12
+ InjectionPause = 1
13
+ InjectionSign = 2
14
+ InjectionError = 3
15
+
16
+ # commands to Client
17
+ InjectionProject = 4
18
+ InjectionLog = 5
19
+ InjectionSigned = 6
20
+ InjectionLoad = 7
21
+ InjectionInject = 8
22
+ InjectionXprobe = 9
23
+ InjectionEval = 10
24
+ InjectionVaccineSettingChanged = 11
25
+
26
+ InjectionEOF = ~0
27
+ end
@@ -0,0 +1,33 @@
1
+ require 'listen'
2
+
3
+ class FileWatcher
4
+ def initialize(path)
5
+ @path = path
6
+ @listener = nil
7
+ end
8
+
9
+ def startWatcher
10
+ if File.directory?(@path) == false
11
+ @path = File.dirname(@path)
12
+ if File.directory?(@path)
13
+ puts "watcher path not exist: #{@path}"
14
+ return
15
+ end
16
+ end
17
+
18
+ @listener = Listen.to(@path, only: onlyReg) do |modified, added, removed|
19
+ modified.each { |path| path.force_encoding('utf-8') }
20
+ yield(modified) unless modified.empty?
21
+ # added.each { |path| path.force_encoding('utf-8') }
22
+ # removed.each { |path| path.force_encoding('utf-8') }
23
+ end
24
+
25
+ @listener.start
26
+ sleep
27
+ end
28
+
29
+ def onlyReg
30
+ /\.m$/
31
+ end
32
+
33
+ end
data/lib/hotreload.rb ADDED
@@ -0,0 +1,140 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ #!/usr/bin/ruby -w
3
+ # -*- coding : utf-8 -*-
4
+ require 'server'
5
+ require 'config'
6
+ require 'file_watcher'
7
+ require 'signer'
8
+ include Config
9
+ include Command
10
+
11
+ class HotReload
12
+ def self.test(path)
13
+ puts "success, path is #{path}"
14
+ end
15
+
16
+ def initialize
17
+ @projectInjected = Hash.new
18
+ @pending = []
19
+ end
20
+
21
+ def startServer(projectpath)
22
+ @projectPath = File.expand_path("..", projectpath)
23
+ @server = Server.new
24
+ @server.run
25
+
26
+ # get current dir
27
+ @server.sendMessage(@projectPath)
28
+
29
+ # tell client the project being watched
30
+ projectfile = "#{@projectPath}/*.xcworkspace"
31
+ files_sorted_by_time = Dir[projectfile].sort_by{ |f| File.mtime(f) }
32
+ projectfile = files_sorted_by_time[0]
33
+ if projectfile == nil
34
+ projectfile = "#{@projectPath}/*.xcodeproj"
35
+ files_sorted_by_time = Dir[projectfile].sort_by{ |f| File.mtime(f) }
36
+ projectfile = files_sorted_by_time[0]
37
+ end
38
+
39
+ if readMessage != Config::HOTRELOAD_KEY
40
+ puts "not the validate client"
41
+ return
42
+ end
43
+
44
+ # client spcific data for building
45
+ frameworkPath = readMessage
46
+ arch = readMessage
47
+
48
+ @lastInjected = @projectInjected[projectfile]
49
+ if @lastInjected == nil
50
+ @lastInjected = Hash.new
51
+ @projectInjected[projectfile] = @lastInjected
52
+ end
53
+
54
+ executable = readMessage
55
+ if executable != nil
56
+ executableBuild = File.mtime(executable).tv_sec
57
+ @lastInjected.each do |key, value|
58
+ if File.extname(key) != ".storyboard" && File.extname(key) != "xib" && File.mtime(key).tv_sec > executable
59
+ inject(key)
60
+ end
61
+ end
62
+ else
63
+ return
64
+ end
65
+
66
+ listenCommand
67
+
68
+ setProject(projectfile)
69
+
70
+ @watcher = nil
71
+
72
+ end
73
+
74
+ def readInt
75
+ @server.readInt
76
+ end
77
+
78
+ def readMessage
79
+ @server.readMessage
80
+ end
81
+
82
+ def inject(source)
83
+ Thread.new do
84
+ @server.sendCommand(Command::InjectionInject, source)
85
+ end
86
+ end
87
+
88
+ def changeFiles(changeFiles)
89
+ now = Time.now.to_i
90
+ changeFiles.each do |file|
91
+ unless @pending.include?(file)
92
+ time = @lastInjected[file]
93
+ if time == nil || now > time
94
+ @lastInjected[file] = now
95
+ @pending.push(file)
96
+ end
97
+ end
98
+ end
99
+
100
+ @pending.each do |file|
101
+ inject(file)
102
+ end
103
+ @pending.clear
104
+
105
+ end
106
+
107
+ def setProject(projectFile)
108
+ @server.sendCommand(Command::InjectionProject, projectFile)
109
+ # /Users/shantj/Documents/workspace/third/injection
110
+ @watcher = FileWatcher.new(@projectPath)
111
+ # @watcher = FileWatcher.new('/Users/shantj/Documents/workspace/third/injection') TODO
112
+ @watcher.startWatcher do |file|
113
+ changeFiles(file)
114
+ end
115
+ end
116
+
117
+ def listenCommand
118
+ Thread.new do
119
+ while (command = readInt) != Command::InjectionEOF
120
+ case command
121
+ when Command::InjectionComplete
122
+ puts "Injection Complete"
123
+ when Command::InjectionPause
124
+ when Command::InjectionSign
125
+ dylib = readMessage
126
+ signer = Signer.new
127
+ ret = signer.codeSignDylib(dylib)
128
+ @server.sendCommand(Command::InjectionSigned, ret ? '1' : '0')
129
+ when Command::InjectionError
130
+ puts "Injection error: #{readMessage}"
131
+ else
132
+ puts "InjectionServer: Unexpected case #{command}"
133
+ exit
134
+ end
135
+ end
136
+ puts "command end"
137
+ end
138
+ end
139
+
140
+ end
data/lib/main.rb ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby -w
2
+ # -*- coding : utf-8 -*-
3
+ require_relative 'hotreload'
4
+
5
+ @server = HotReload.new
6
+ @server.startServer("/Users/shantj/Documents/workspace/third/HotReloadClient/Example/Pods")
7
+
8
+
data/lib/server.rb ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/ruby -w
2
+ # -*- coding : utf-8 -*-
3
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
4
+ require 'socket'
5
+ require 'config'
6
+ include Socket::Constants
7
+ include Config
8
+
9
+ class Server
10
+ def run
11
+ @server = Socket.new(AF_INET, SOCK_STREAM, 0)
12
+ sockaddr = Socket.sockaddr_in(Config::PORT, Config::HOST)
13
+ @server.bind(sockaddr)
14
+ @server.listen(1)
15
+ @client, _ = @server.accept
16
+ end
17
+
18
+ def stop
19
+ if @client != nil
20
+ @client.close
21
+ @client = nil
22
+ end
23
+
24
+ if @server != nil
25
+ @server.close
26
+ @server = nil
27
+ end
28
+ end
29
+
30
+ def readInt
31
+ raise "client not connect #{@host}:#{@port}, please check" if @client == nil
32
+
33
+ begin
34
+ message = @client.recvfrom(4)[0]
35
+ msgInt = message.unpack("L")[0]
36
+ rescue StandardError => e
37
+ puts e.message
38
+ puts e.backtrace.inspect
39
+ end
40
+
41
+ msgInt
42
+ end
43
+
44
+ def readMessage
45
+ raise "client not connect #{@host}:#{@port}, please check" if @client == nil
46
+
47
+ begin
48
+ len = readInt
49
+ if len == ~0
50
+ return nil
51
+ end
52
+
53
+ message = @client.recvfrom(len)[0]
54
+ rescue StandardError => e
55
+ puts e.message
56
+ puts e.backtrace.inspect
57
+ end
58
+
59
+ message
60
+ end
61
+
62
+ def sendMessage(msg)
63
+ raise "client not connect #{@host}:#{@port}, please check" if @client == nil
64
+
65
+ begin
66
+ @client.write([msg.bytesize].pack("L"))
67
+ @client.write(msg)
68
+ rescue StandardError => e
69
+ puts e.message
70
+ puts e.backtrace.inspect
71
+ end
72
+
73
+ true
74
+ end
75
+
76
+ def sendCommand(command, msg)
77
+ raise "client not connect #{@host}:#{@port}, please check" if @client == nil
78
+
79
+ begin
80
+ @client.write([command].pack("L"))
81
+ sendMessage(msg)
82
+ rescue StandardError => e
83
+ puts e.message
84
+ puts e.backtrace.inspect
85
+ end
86
+
87
+ true
88
+ end
89
+
90
+ end
data/lib/signer.rb ADDED
@@ -0,0 +1,14 @@
1
+ class Signer
2
+ # sign the dynamic library
3
+ #
4
+ # @param dylib the dylib's path
5
+ #
6
+ # @return true or false
7
+ #
8
+ def codeSignDylib(dylib)
9
+ command = "export CODESIGN_ALLOCATE=/Applications/Xcode.app"
10
+ "/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/codesign_allocate; "
11
+ "/usr/bin/codesign --force -s '-' '#{dylib}'"
12
+ system(command)
13
+ end
14
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hotreload
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - shantj
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-05-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.17'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: listen
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '='
60
+ - !ruby/object:Gem::Version
61
+ version: 3.1.5
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '='
67
+ - !ruby/object:Gem::Version
68
+ version: 3.1.5
69
+ description: hot reload changed files
70
+ email:
71
+ - 405812883@qq.com
72
+ executables:
73
+ - hotreload
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - bin/hotreload
78
+ - lib/config.rb
79
+ - lib/file_watcher.rb
80
+ - lib/hotreload.rb
81
+ - lib/main.rb
82
+ - lib/server.rb
83
+ - lib/signer.rb
84
+ homepage: https://github.com/shantj/hotreload.git
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubyforge_project:
104
+ rubygems_version: 2.6.14
105
+ signing_key:
106
+ specification_version: 4
107
+ summary: hot reload changed files
108
+ test_files: []