guard-tishadow 0.0.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 1956d3ccec5d7d9e724904d8f8e01efb1c960cf8
4
+ data.tar.gz: 450a8278a146b34c3ca93f85fee543eda7a5e5ba
5
+ SHA512:
6
+ metadata.gz: 4f372f71a620c394c81427026b55effdf115e1ec156bd1025399bcf8fd4c967a18345f92da5152468f6e9f09c37c481c6482819a670d625947e573a1da0ba4f0
7
+ data.tar.gz: a8e0c386315e3e0a0450a640caef914166f3717495496b10c6aaf92e17363709fa1a71e7dae6dce3ef03061bacbad91e22d31d88483efe18f492c3dbd91080ba
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .ruby-version
19
+ .ruby-gemset
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in guard-tishadow.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ian Duggan
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,35 @@
1
+ # Guard::Tishadow
2
+
3
+ Guard::Tishadow manages [TIShadow](http://tishadow.yydigital.com/) for easier Titanium development.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'guard-tishadow'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install guard-tishadow
18
+
19
+ ## Usage
20
+
21
+ ```
22
+ guard 'tishadow', :app_root => "testapp" do
23
+ watch(%r{^testapp/app/.*})
24
+ watch(%r{^testapp/tiapp.xml})
25
+ watch(%r{^testapp/spec/(.*)\.js})
26
+ end
27
+ ```
28
+
29
+ ## Contributing
30
+
31
+ 1. Fork it
32
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
33
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
34
+ 4. Push to the branch (`git push origin my-new-feature`)
35
+ 5. Create new Pull Request
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'guard/tishadow/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "guard-tishadow"
8
+ spec.version = Guard::TishadowVersion::VERSION
9
+ spec.authors = ["Ian Duggan"]
10
+ spec.email = ["ian@ianduggan.net"]
11
+ spec.description = %q{Start tishadow server and push updates on changes to app directory}
12
+ spec.summary = %q{Start tishadow server and push updates on changes to app directory}
13
+ spec.homepage = "http://github.com/ijcd/guard-tishadow"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency "celluloid"
25
+ spec.add_dependency "childprocess"
26
+ end
@@ -0,0 +1,135 @@
1
+ require 'guard'
2
+ require 'guard/plugin'
3
+
4
+ module Guard
5
+ class Tishadow < Plugin
6
+
7
+ autoload :Server, 'guard/tishadow/server'
8
+ autoload :Builder, 'guard/tishadow/builder'
9
+ autoload :PeriodicCaller, 'guard/tishadow/periodic_caller'
10
+
11
+ # Initializes a Guard plugin.
12
+ # Don't do any work here, especially as Guard plugins get initialized even
13
+ # if they are not in an active group!
14
+ #
15
+ # @param [Hash] options the Guard plugin options
16
+ # @option options [Array<Guard::Watcher>] watchers the Guard plugin file
17
+ # watchers
18
+ # @option options [Symbol] group the group this Guard plugin belongs to
19
+ # @option options [Boolean] any_return allow any object to be returned from
20
+ # a watcher
21
+ #
22
+ def initialize(options = {})
23
+ @build_command = options.delete(:build_command)
24
+ @spec_command = options.delete(:spec_command)
25
+ @verbose = options.has_key?(:verbose) ? options.delete(:verbose) : false
26
+ @update = options.has_key?(:update) ? options.delete(:update) : false
27
+ @spec = options.has_key?(:spec) ? options.delete(:spec) : true
28
+ @app_root = options.delete(:app_root)
29
+ super
30
+ end
31
+
32
+ # Called once when Guard starts. Please override initialize method to
33
+ # init stuff.
34
+ #
35
+ # @raise [:task_has_failed] when start has failed
36
+ # @return [Object] the task result
37
+ #
38
+ # @!method start
39
+ def start
40
+ Server.supervise_as :tishadow_server, self, :run_on_connect
41
+ Builder.supervise_as :tishadow_builder, :build_command => @build_command, :verbose => @verbose, :update => @update, :spec => @spec, :app_root => @app_root
42
+ @builder = Celluloid::Actor[:tishadow_builder]
43
+ @server = Celluloid::Actor[:tishadow_server]
44
+ @server.async.start
45
+ end
46
+
47
+ def run_on_connect
48
+ @builder.run
49
+ end
50
+
51
+ # Called when `stop|quit|exit|s|q|e + enter` is pressed (when Guard
52
+ # quits).
53
+ #
54
+ # @raise [:task_has_failed] when stop has failed
55
+ # @return [Object] the task result
56
+ #
57
+ # @!method stop
58
+ def stop
59
+ @builder.terminate
60
+ @server.terminate
61
+ end
62
+
63
+ # Called when `reload|r|z + enter` is pressed.
64
+ # This method should be mainly used for "reload" (really!) actions like
65
+ # reloading passenger/spork/bundler/...
66
+ #
67
+ # @raise [:task_has_failed] when reload has failed
68
+ # @return [Object] the task result
69
+ #
70
+ # @!method reload
71
+ def reload
72
+ UI.info "Reloading Guard::TiShadow"
73
+ stop
74
+ start
75
+ end
76
+
77
+ # Called when just `enter` is pressed
78
+ # This method should be principally used for long action like running all
79
+ # specs/tests/...
80
+ #
81
+ # @raise [:task_has_failed] when run_all has failed
82
+ # @return [Object] the task result
83
+ #
84
+ # @!method run_all
85
+ def run_all
86
+ #run_on_changes(Watcher.match_files(self, Dir.glob("**/*.*")))
87
+ @builder.notify(true)
88
+ end
89
+
90
+ # Default behaviour on file(s) changes that the Guard plugin watches.
91
+ #
92
+ # @param [Array<String>] paths the changes files or paths
93
+ # @raise [:task_has_failed] when run_on_changes has failed
94
+ # @return [Object] the task result
95
+ #
96
+ # @!method run_on_changes(paths)
97
+ def run_on_changes(paths)
98
+ @builder.notify
99
+ end
100
+
101
+ # Called on file(s) additions that the Guard plugin watches.
102
+ #
103
+ # @param [Array<String>] paths the changes files or paths
104
+ # @raise [:task_has_failed] when run_on_additions has failed
105
+ # @return [Object] the task result
106
+ #
107
+ # @!method run_on_additions(paths)
108
+ def run_on_additions(paths)
109
+ @builder.notify
110
+ end
111
+
112
+ # Called on file(s) modifications that the Guard plugin watches.
113
+ #
114
+ # @param [Array<String>] paths the changes files or paths
115
+ # @raise [:task_has_failed] when run_on_modifications has failed
116
+ # @return [Object] the task result
117
+ #
118
+ # @!method run_on_modifications(paths)
119
+ def run_on_modifications(paths)
120
+ @builder.notify
121
+ end
122
+
123
+ # Called on file(s) removals that the Guard plugin watches.
124
+ #
125
+ # @param [Array<String>] paths the changes files or paths
126
+ # @raise [:task_has_failed] when run_on_removals has failed
127
+ # @return [Object] the task result
128
+ #
129
+ # @!method run_on_removals(paths)
130
+ def run_on_removal(paths)
131
+ @builder.notify
132
+ end
133
+
134
+ end
135
+ end
@@ -0,0 +1,103 @@
1
+ require 'celluloid'
2
+ require 'guard/tishadow/periodic_caller'
3
+
4
+ module Guard
5
+ class Tishadow
6
+ class Builder
7
+
8
+ include Celluloid
9
+
10
+ def initialize(options = {})
11
+ @build_command = options.delete(:build_command) || "alloy compile --config platform=ios 2>&1 && tishadow close && tishadow run"
12
+ @spec_command = options.delete(:spec_command) || "tishadow spec"
13
+ @verbose = options.delete(:verbose)
14
+ @update = options.delete(:update)
15
+ @spec = options.delete(:spec)
16
+ @app_root = options.delete(:app_root)
17
+ @update = true if @update.nil?
18
+ @last_notice_at = nil
19
+ @clock = nil
20
+ @reload = false
21
+ end
22
+
23
+ def notify(reload = false)
24
+ @reload ||= reload
25
+ set_notified
26
+ start_clock unless @clock
27
+ end
28
+
29
+ def start_clock
30
+ @clock = PeriodCaller.new 1, :maybe_build, Celluloid.current_actor
31
+ end
32
+
33
+ def stop_clock
34
+ @clock.terminate
35
+ @clock = nil
36
+ end
37
+
38
+ def set_notified
39
+ @last_notice_at = Time.now
40
+ end
41
+
42
+ def clear_notified
43
+ @last_notice_at = nil
44
+ end
45
+
46
+ def time_to_build?
47
+ (Time.now - @last_notice_at) > 1
48
+ end
49
+
50
+ def run
51
+ shell_command(@build_command)
52
+ UI.info("Alloy compile and tishadow run complete.")
53
+ end
54
+
55
+ def update
56
+ shell_command("#{@build_command} --update")
57
+ UI.info("Alloy compile and tishadow run --update complete.")
58
+ end
59
+
60
+ def spec
61
+ shell_command(@spec_command)
62
+ UI.info("Spec run complete.")
63
+ end
64
+
65
+ def run_or_update
66
+ UI.info "Tishadow building at #{Time.now} with \"#{@build_command}\""
67
+ if @reload || !@update
68
+ @reload = false
69
+ run
70
+ else
71
+ update
72
+ end
73
+ spec if @spec
74
+ end
75
+
76
+ # TODO: watch the process result and treat errors more carefully
77
+ def maybe_build
78
+ return unless @last_notice_at
79
+ if time_to_build?
80
+ UI.info "Tishadow building at #{Time.now} with \"#{@build_command}\""
81
+ run_or_update
82
+ clear_notified
83
+ stop_clock
84
+ end
85
+ end
86
+
87
+ def shell_command(cmd)
88
+ cmd = "(cd #{@app_root} && #{cmd})" if @app_root
89
+ UI.info(cmd)
90
+ format_result(`#{cmd}`)
91
+ end
92
+
93
+ def format_result(result)
94
+ if @verbose
95
+ UI.info(result)
96
+ else
97
+ UI.error(result.split("\n").grep(/error/i).join("\n"))
98
+ end
99
+ end
100
+
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,25 @@
1
+ require 'celluloid'
2
+
3
+ module Guard
4
+ class Tishadow
5
+ class PeriodCaller
6
+
7
+ include Celluloid
8
+
9
+ def initialize(interval, signal, recipient)
10
+ @interval = interval
11
+ @signal = signal
12
+ @recipient = recipient
13
+ self.async.start
14
+ end
15
+
16
+ def start
17
+ loop do
18
+ sleep @interval
19
+ @recipient.send(@signal)
20
+ end
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,85 @@
1
+ require 'celluloid'
2
+ require 'childprocess'
3
+
4
+ module Guard
5
+ class Tishadow
6
+ class Server
7
+
8
+ include Celluloid
9
+
10
+ def initialize(who_to_notify, how_to_notify)
11
+ @who_to_notify = who_to_notify
12
+ @how_to_notify = how_to_notify
13
+ end
14
+
15
+ def start
16
+ UI.info 'Starting tishadow server'
17
+
18
+ ChildProcess.posix_spawn = true
19
+ @proc = ChildProcess.build("tishadow", "server")
20
+ stdout, stdout_writer = IO.pipe
21
+ stderr, stderr_writer = IO.pipe
22
+ stdout.sync = true
23
+ stderr.sync = true
24
+ @proc.io.stdout = stdout_writer
25
+ @proc.io.stderr = stderr_writer
26
+ @proc.start
27
+
28
+ # read stdout
29
+ Thread.new do
30
+ UI.info "reading stdout"
31
+ stdout.each do |line|
32
+ # if line =~ %r{\[(\S+), (\S+), (\S+)\] Connected}
33
+ # UI.info "Connected #{$1}, #{$2}, #{$3} --> sending notification to #{@who_to_notify}#@#{@how_to_notify}"
34
+ # @who_to_notify.send @how_to_notify if @who_to_notify && @how_to_notify
35
+ # end
36
+ UI.info "TISHADOW stdout: #{line}"
37
+ end
38
+ end
39
+
40
+ # read stderr
41
+ Thread.new do
42
+ stderr.each_line do |line|
43
+ UI.error "TISHADOW stderr: #{line}"
44
+ end
45
+ end
46
+
47
+ # wait on the process for cleanup
48
+ Thread.new do
49
+ begin
50
+ @proc.wait
51
+ UI.info "*********** TiShadow Server Terminated *************"
52
+ self.terminate
53
+ ensure
54
+ @proc.stop if @proc
55
+ end
56
+ end
57
+
58
+ UI.info 'Started tishadow server'
59
+
60
+ at_exit do
61
+ stop
62
+ end
63
+
64
+ #loop { sleep 1 }
65
+ end
66
+
67
+ def stop
68
+ return unless @proc && @proc.alive?
69
+ @proc.stop
70
+ # begin
71
+ # @proc.poll_for_exit(10)
72
+ # rescue ChildProcess::TimeoutError
73
+ # @proc.stop # tries increasingly harsher methods to kill the process.
74
+ # end
75
+ UI.info "*********** TiShadow Server Stopped ********************"
76
+ end
77
+
78
+ finalizer do
79
+ UI.info "*********** TiShadow Server Finalizing ********************"
80
+ self.async.stop
81
+ end
82
+
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,6 @@
1
+ # Changes in any watched directories or files will trigger a tishadow
2
+ # rebuild
3
+
4
+ guard :tishadow do
5
+ watch('app')
6
+ end
@@ -0,0 +1,5 @@
1
+ module Guard
2
+ class TishadowVersion
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-tishadow
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ian Duggan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-04-05 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.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: celluloid
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: childprocess
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Start tishadow server and push updates on changes to app directory
70
+ email:
71
+ - ian@ianduggan.net
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - Gemfile
78
+ - LICENSE.txt
79
+ - README.md
80
+ - Rakefile
81
+ - guard-tishadow.gemspec
82
+ - lib/guard/tishadow.rb
83
+ - lib/guard/tishadow/builder.rb
84
+ - lib/guard/tishadow/periodic_caller.rb
85
+ - lib/guard/tishadow/server.rb
86
+ - lib/guard/tishadow/templates/Guardfile
87
+ - lib/guard/tishadow/version.rb
88
+ homepage: http://github.com/ijcd/guard-tishadow
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.2.2
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Start tishadow server and push updates on changes to app directory
112
+ test_files: []
113
+ has_rdoc: