hotreload 0.1.0

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.
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: []