guard-typescript 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.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2014 Payton Yao
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,273 @@
1
+ # Guard::TypeScript
2
+
3
+ Guard::TypeScript compiles or validates your TypeScripts automatically when files are modified.
4
+
5
+ This is a clone of [Guard CoffeeScript](https://github.com/guard/guard-coffeescript) that was shamelessly stolen
6
+ and modified to work with TypeScript.
7
+
8
+ If you have any questions please join us on our [Google group](http://groups.google.com/group/guard-dev) or on `#guard`
9
+ (irc.freenode.net).
10
+
11
+ ## Install
12
+
13
+ The simplest way to install Guard is to use [Bundler](http://gembundler.com/).
14
+ Please make sure to have [Guard](https://github.com/guard/guard) installed.
15
+
16
+ Add Guard::TypeScript to your `Gemfile`:
17
+
18
+ ```ruby
19
+ group :development do
20
+ gem 'guard-typescript'
21
+ end
22
+ ```
23
+ Add the default Guard::TypeScript template to your `Guardfile` by running:
24
+
25
+ ```bash
26
+ $ guard init typescript
27
+ ```
28
+
29
+ ## JSON
30
+
31
+ The JSON library is also required but is not explicitly stated as a gem dependency. If you're on Ruby 1.8 you'll need
32
+ to install the `json` or `json_pure` gem. On Ruby 1.9, JSON is included in the standard library.
33
+
34
+ ## TypeScript
35
+
36
+ Guard::TypeScript uses [Typescript Node](https://github.com/typescript-ruby/typescript-node-ruby) to compile the TypeScripts.
37
+
38
+ ## Usage
39
+
40
+ Please read the [Guard usage documentation](https://github.com/guard/guard#readme).
41
+
42
+ ## Guardfile
43
+
44
+ Guard::TypeScript can be adapted to all kind of projects. Please read the
45
+ [Guard documentation](https://github.com/guard/guard#readme) for more information about the Guardfile DSL.
46
+
47
+ ### Ruby project
48
+
49
+ In a Ruby project you want to configure your input and output directories.
50
+
51
+ ```ruby
52
+ guard 'typescript', :input => 'typescripts', :output => 'javascripts'
53
+ ```
54
+
55
+ If your output directory is the same as the input directory, you can simply skip it:
56
+
57
+ ```ruby
58
+ guard 'typescript', :input => 'javascripts'
59
+ ```
60
+
61
+ ### Rails app with the asset pipeline
62
+
63
+ With the introduction of the [asset pipeline](http://guides.rubyonrails.org/asset_pipeline.html) in Rails 3.1 there is
64
+ no need to compile your TypeScripts with this Guard.
65
+
66
+ However, if you would still like to have feedback on the validation of your TypeScripts
67
+ (preferably with a Growl notification) directly after you save a change, then you can still
68
+ use this Guard and simply skip generation of the output file:
69
+
70
+ ```ruby
71
+ guard 'typescript', :input => 'app/assets/javascripts', :noop => true
72
+ ```
73
+
74
+ This give you a faster compilation feedback compared to making a subsequent request to your Rails application. If you
75
+ just want to be notified when an error occurs you can hide the success compilation message:
76
+
77
+ ```ruby
78
+ guard 'typescript', :input => 'app/assets/javascripts', :noop => true, :hide_success => true
79
+ ```
80
+
81
+ ### Rails app without the asset pipeline
82
+
83
+ Without the asset pipeline you just define an input and output directory like within a normal Ruby project:
84
+
85
+ ```ruby
86
+ guard 'typescript', :input => 'app/typescripts', :output => 'public/javascripts'
87
+ ```
88
+
89
+ ## Options
90
+
91
+ There following options can be passed to Guard::TypeScript:
92
+
93
+ ```ruby
94
+ :input => 'typescripts' # Relative path to the input directory.
95
+ # Files will be added that match end in .ts
96
+ # default: nil
97
+
98
+ :output => 'javascripts' # Relative path to the output directory.
99
+ # default: the path given with the :input option
100
+
101
+ :noop => true # No operation: do not write an output file.
102
+ # default: false
103
+
104
+ :shallow => true # Do not create nested output directories.
105
+ # default: false
106
+
107
+ :source_map => true # Do create the source map file.
108
+ # default: false
109
+
110
+ :source_root => 'typescripts' # Root path for typescript sources.
111
+ # Used in source map to determine root URL for
112
+ # all sources
113
+ # default: nil (using the `:input` directory)
114
+
115
+ :hide_success => true # Disable successful compilation messages.
116
+ # default: false
117
+
118
+ :all_on_start => true # Regenerate all files on startup
119
+ # default: false
120
+
121
+ :error_to_js => true # Print the Typescript error message directly in
122
+ # the JavaScript file
123
+ # default: false
124
+ ```
125
+
126
+ ### Output short notation
127
+
128
+ In addition to the standard configuration, this Guard has a short notation for configure projects with a single input
129
+ and output directory. This notation creates a watcher from the `:input` parameter that matches all TypeScript files
130
+ under the given directory and you don't have to specify a watch regular expression.
131
+
132
+ ```ruby
133
+ guard 'typescript', :input => 'javascripts'
134
+ ```
135
+
136
+ ### Nested directories
137
+
138
+ The Guard detects by default nested directories and creates these within the output directory. The detection is based on
139
+ the match of the watch regular expression:
140
+
141
+ A file
142
+
143
+ ```ruby
144
+ /app/typescripts/ui/buttons/toggle_button.ts
145
+ ```
146
+
147
+ that has been detected by the watch
148
+
149
+ ```ruby
150
+ watch(%r{^app/typescripts/(.+\.ts)$})
151
+ ```
152
+
153
+ with an output directory of
154
+
155
+ ```ruby
156
+ :output => 'public/javascripts/compiled'
157
+ ```
158
+
159
+ will be compiled to
160
+
161
+ ```ruby
162
+ public/javascripts/compiled/ui/buttons/toggle_button.js
163
+ ```
164
+
165
+ Note the parenthesis around the `.+\.ts`. This enables Guard::TypeScript to place the full path that was matched
166
+ inside the parenthesis into the proper output directory.
167
+
168
+ This behavior can be switched off by passing the option `:shallow => true` to the Guard, so that all JavaScripts will be
169
+ compiled directly to the output directory.
170
+
171
+ ### Multiple source directories
172
+
173
+ The Guard short notation
174
+
175
+ ```ruby
176
+ guard 'typescript', :input => 'app/typescripts', :output => 'public/javascripts/compiled'
177
+ ```
178
+
179
+ will be internally converted into the standard notation by adding `/(.+\.ts)` to the `input` option string and
180
+ create a Watcher that is equivalent to:
181
+
182
+ ```ruby
183
+ guard 'typescript', :output => 'public/javascripts/compiled' do
184
+ watch(%r{^app/typescripts/(.+\.ts)$})
185
+ end
186
+ ```
187
+
188
+ To add a second source directory that will be compiled to the same output directory, just add another watcher:
189
+
190
+ ```ruby
191
+ guard 'typescript', :input => 'app/typescripts', :output => 'public/javascripts/compiled' do
192
+ watch(%r{lib/typescripts/(.+\.ts)})
193
+ end
194
+ ```
195
+
196
+ which is equivalent to:
197
+
198
+ ```ruby
199
+ guard 'typescript', :output => 'public/javascripts/compiled' do
200
+ watch(%r{app/typescripts/(.+\.ts)})
201
+ watch(%r{lib/typescripts/(.+\.ts)})
202
+ end
203
+ ```
204
+
205
+ ## Issues
206
+
207
+ You can report issues and feature requests to [GitHub Issues](https://github.com/jabbawookiees/guard-typescript/issues). Try to figure out
208
+ where the issue belongs to: Is it an issue with Guard itself or with a Guard::TypeScript?
209
+
210
+ When you file an issue, please try to follow to these simple rules if applicable:
211
+
212
+ * Make sure you run Guard with `bundle exec` first.
213
+ * Add debug information to the issue by running Guard with the `--debug` option.
214
+ * Add your `Guardfile` and `Gemfile` to the issue.
215
+ * Make sure that the issue is reproducible with your description.
216
+
217
+ ## Development
218
+
219
+ - Source hosted at [GitHub](https://github.com/jabbawookiees/guard-typescript).
220
+
221
+ Pull requests are very welcome! Please try to follow these simple rules if applicable:
222
+
223
+ * Please create a topic branch for every separate change you make.
224
+ * Make sure your patches are well tested.
225
+ * Update the [Yard](http://yardoc.org/) documentation.
226
+ * Update the README.
227
+ * Update the CHANGELOG for noteworthy changes.
228
+ * Please **do not change** the version number.
229
+
230
+ For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on
231
+ `#guard` (irc.freenode.net).
232
+
233
+ ## Author
234
+
235
+ Developed by Payton Yao.
236
+
237
+ ## Contributors
238
+
239
+ See the GitHub list of [contributors](https://github.com/jabbawookiees/guard-typescript/contributors).
240
+
241
+ ## Acknowledgment
242
+
243
+ * [Michael Kessler](https://twitter.com/#!/netzpirat) for [Guard CoffeeScript](https://github.com/netzpirat/guard-coffeescript/),
244
+ from which this was shamelessly stolen from and modified to work with TypeScript.
245
+ * The [Guard Team](https://github.com/guard/guard/contributors) for giving us such a nice piece of software
246
+ that is so easy to extend, one *has* to make a plugin for it!
247
+ * All the authors of the numerous [Guards](https://github.com/guard) available for making the Guard ecosystem
248
+ so much growing and comprehensive.
249
+
250
+ ## License
251
+
252
+ (The MIT License)
253
+
254
+ Copyright (c) 2014 Payton Yao
255
+
256
+ Permission is hereby granted, free of charge, to any person obtaining
257
+ a copy of this software and associated documentation files (the
258
+ 'Software'), to deal in the Software without restriction, including
259
+ without limitation the rights to use, copy, modify, merge, publish,
260
+ distribute, sublicense, and/or sell copies of the Software, and to
261
+ permit persons to whom the Software is furnished to do so, subject to
262
+ the following conditions:
263
+
264
+ The above copyright notice and this permission notice shall be
265
+ included in all copies or substantial portions of the Software.
266
+
267
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
268
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
269
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
270
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
271
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
272
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
273
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,77 @@
1
+ module Guard
2
+ class TypeScript
3
+
4
+ # The Guard::TypeScript formatter collects console and
5
+ # system notification methods and enhances them with
6
+ # some color information.
7
+ #
8
+ module Formatter
9
+ class << self
10
+
11
+ # Print an info message to the console.
12
+ #
13
+ # @param [String] message the message to print
14
+ # @param [Hash] options the output options
15
+ # @option options [Boolean] :reset reset the UI
16
+ #
17
+ def info(message, options = { })
18
+ ::Guard::UI.info(message, options)
19
+ end
20
+
21
+ # Print a debug message to the console.
22
+ #
23
+ # @param [String] message the message to print
24
+ # @param [Hash] options the output options
25
+ # @option options [Boolean] :reset reset the UI
26
+ #
27
+ def debug(message, options = { })
28
+ ::Guard::UI.debug(message, options)
29
+ end
30
+
31
+ # Print a red error message to the console.
32
+ #
33
+ # @param [String] message the message to print
34
+ # @param [Hash] options the output options
35
+ # @option options [Boolean] :reset reset the UI
36
+ #
37
+ def error(message, options = { })
38
+ ::Guard::UI.error(color(message, ';31'), options)
39
+ end
40
+
41
+ # Print a green success message to the console.
42
+ #
43
+ # @param [String] message the message to print
44
+ # @param [Hash] options the output options
45
+ # @option options [Boolean] :reset reset the UI
46
+ #
47
+ def success(message, options = { })
48
+ stamped_message = "#{Time.now.strftime('%r')} #{message}"
49
+ ::Guard::UI.info(color(stamped_message, ';32'), options)
50
+ end
51
+
52
+ # Outputs a system notification.
53
+ #
54
+ # @param [String] message the message to print
55
+ # @param [Hash] options the output options
56
+ # @option options [Symbol, String] :image the image to use, either :failed, :pending or :success, or an image path
57
+ # @option options [String] :title the title of the system notification
58
+ #
59
+ def notify(message, options = { })
60
+ ::Guard::Notifier.notify(message, options)
61
+ end
62
+
63
+ private
64
+
65
+ # Print a info message to the console.
66
+ #
67
+ # @param [String] text the text to colorize
68
+ # @param [String] color_code the color code
69
+ #
70
+ def color(text, color_code)
71
+ ::Guard::UI.send(:color_enabled?) ? "\e[0#{ color_code }m#{ text }\e[0m" : text
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,40 @@
1
+ module Guard
2
+ class TypeScript
3
+
4
+ # The inspector verifies of the changed paths are valid
5
+ # for Guard::TypeScript.
6
+ #
7
+ module Inspector
8
+ class << self
9
+
10
+ # Clean the changed paths and return only valid
11
+ # TypeScript files.
12
+ #
13
+ # @param [Array<String>] paths the changed paths
14
+ # @param [Hash] options the clean options
15
+ # @option options [String] :missing_ok don't remove missing files from list
16
+ # @return [Array<String>] the valid spec files
17
+ #
18
+ def clean(paths, options = {})
19
+ paths.uniq!
20
+ paths.compact!
21
+ paths.select { |p| typescript_file?(p, options) }
22
+ end
23
+
24
+ private
25
+
26
+ # Tests if the file is valid.
27
+ #
28
+ # @param [String] path the file
29
+ # @param [Hash] options the clean options
30
+ # @option options [String] :missing_ok don't remove missing files from list
31
+ # @return [Boolean] when the file valid
32
+ #
33
+ def typescript_file?(path, options)
34
+ path =~ /\.(?:ts)$/ && (options[:missing_ok] || File.exists?(path))
35
+ end
36
+
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,236 @@
1
+ require 'ruby-typescript'
2
+
3
+ module Guard
4
+ class TypeScript
5
+ module Runner
6
+ class << self
7
+
8
+ attr_accessor :last_run_failed
9
+
10
+ # The TypeScript runner handles the TypeScript compilation,
11
+ # creates nested directories and the output file, writes the result
12
+ # to the console and triggers optional system notifications.
13
+ #
14
+ # @param [Array<String>] files the spec files or directories
15
+ # @param [Array<Guard::Watcher>] watchers the Guard watchers in the block
16
+ # @param [Hash] options the options for the execution
17
+ # @option options [String] :input the input directory
18
+ # @option options [String] :output the output directory
19
+ # @option options [Boolean] :shallow do not create nested directories
20
+ # @option options [Boolean] :hide_success hide success message notification
21
+ # @option options [Boolean] :noop do not generate an output file
22
+ # @option options [Boolean] :source_map generate the source map files
23
+ # @return [Array<Array<String>, Boolean>] the result for the compilation run
24
+ #
25
+ def run(files, watchers, options = { })
26
+ notify_start(files, options)
27
+ changed_files, errors = compile_files(files, watchers, options)
28
+ notify_result(changed_files, errors, options)
29
+
30
+ [changed_files, errors.empty?]
31
+ end
32
+
33
+ # The remove function deals with TypeScript file removal by
34
+ # locating the output javascript file and removing it.
35
+ #
36
+ # @param [Array<String>] files the spec files or directories
37
+ # @param [Array<Guard::Watcher>] watchers the Guard watchers in the block
38
+ # @param [Hash] options the options for the removal
39
+ # @option options [String] :output the output directory
40
+ # @option options [Boolean] :shallow do not create nested directories
41
+ #
42
+ def remove(files, watchers, options = { })
43
+ removed_files = []
44
+ directories = detect_nested_directories(watchers, files, options)
45
+
46
+ directories.each do |directory, scripts|
47
+ scripts.each do |file|
48
+ javascript = javascript_file_name(file, directory)
49
+ if File.exists?(javascript)
50
+ FileUtils.remove_file(javascript)
51
+ removed_files << javascript
52
+ end
53
+ end
54
+ end
55
+
56
+ if removed_files.length > 0
57
+ message = "Removed #{ removed_files.join(', ') }"
58
+ Formatter.success(message)
59
+ Formatter.notify(message, :title => 'TypeScript results')
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ # Generates a start compilation notification.
66
+ #
67
+ # @param [Array<String>] files the generated files
68
+ # @param [Hash] options the options for the execution
69
+ # @option options [Boolean] :noop do not generate an output file
70
+ #
71
+ def notify_start(files, options)
72
+ message = options[:message] || (options[:noop] ? 'Verify ' : 'Compile ') + files.join(', ')
73
+ Formatter.info(message, :reset => true)
74
+ end
75
+
76
+ # Compiles all TypeScript files and writes the JavaScript files.
77
+ #
78
+ # @param [Array<String>] files the files to compile
79
+ # @param [Array<Guard::Watcher>] watchers the Guard watchers in the block
80
+ # @param [Hash] options the options for the execution
81
+ # @return [Array<Array<String>, Array<String>] the result for the compilation run
82
+ #
83
+ def compile_files(files, watchers, options)
84
+ errors = []
85
+ changed_files = []
86
+ directories = detect_nested_directories(watchers, files, options)
87
+
88
+ directories.each do |directory, scripts|
89
+ scripts.each do |file|
90
+ begin
91
+ js, map = compile(file, directory, options)
92
+ if options[:noop]
93
+ if File.exists?(js)
94
+ FileUtils.remove_file(js)
95
+ end
96
+ if map and File.exists?(map)
97
+ FileUtils.remove_file(map)
98
+ end
99
+ end
100
+ changed_files << js << map
101
+ rescue => e
102
+ error_message = file + ': ' + e.message.to_s
103
+
104
+ if options[:error_to_js]
105
+ js_error_message = "throw \"#{ error_message }\";"
106
+ changed_files << write_javascript_file(js_error_message, nil, file, directory, options)
107
+ end
108
+
109
+ errors << error_message
110
+ Formatter.error(error_message)
111
+ end
112
+ end
113
+ end
114
+ [changed_files.flatten.compact, errors]
115
+ end
116
+
117
+ # Compile the TypeScript and generate the source map.
118
+ #
119
+ # @param [String] filename the TypeScript file name
120
+ # @param [Hash] options the options for the execution
121
+ # @option options [Boolean] :source_map generate the source map files
122
+ # @return [Array<String, String>] the JavaScript filename and the source map filename
123
+ #
124
+ def compile(filename, directory, options)
125
+ options = options.clone
126
+ options[:output] = javascript_file_name(filename, directory)
127
+ result = ::TypeScript.compile_file(filename, options)
128
+ if options[:source_map]
129
+ js, map = result[:js], result[:source_map]
130
+ else
131
+ js = result[:js]
132
+ end
133
+
134
+ [js, map]
135
+ end
136
+
137
+ # Analyzes the CoffeeScript compilation output and creates the
138
+ # nested directories and writes the output file.
139
+ #
140
+ # @param [String] js the JavaScript content
141
+ # @param [String] map the source map content
142
+ # @param [String] file the CoffeeScript file name
143
+ # @param [String] directory the output directory
144
+ # @param [Hash] options the options for the execution
145
+ # @option options [Boolean] :noop do not generate an output file
146
+ # @return [String] the JavaScript file name
147
+ #
148
+ def write_javascript_file(js, map, file, directory, options)
149
+ directory = Dir.pwd if !directory || directory.empty?
150
+ filename = javascript_file_name(file, directory)
151
+
152
+ return filename if options[:noop]
153
+
154
+ if options[:source_map]
155
+ map_name = filename + '.map'
156
+ js += "\n/*\n//@ sourceMappingURL=#{File.basename(map_name)}\n*/\n"
157
+ end
158
+
159
+ FileUtils.mkdir_p(File.expand_path(directory)) if !File.directory?(directory)
160
+ File.open(File.expand_path(filename), 'w') { |f| f.write(js) }
161
+
162
+ if options[:source_map]
163
+ File.open(File.expand_path(map_name), 'w') { |f| f.write(map) }
164
+ [filename, map_name]
165
+ else
166
+ filename
167
+ end
168
+ end
169
+
170
+ # Calculates the output filename from the typescript filename and
171
+ # the output directory
172
+ #
173
+ # @param [string] filename the TypeScript file name
174
+ # @param [String] directory the output directory
175
+ #
176
+ def javascript_file_name(filename, directory)
177
+ File.join(directory, File.basename(filename.gsub(/((?:js\.)?(?:ts))$/, 'js')))
178
+ end
179
+
180
+ # Detects the output directory for each TypeScript file. Builds
181
+ # the product of all watchers and assigns to each directory
182
+ # the files to which it belongs to.
183
+ #
184
+ # @param [Array<Guard::Watcher>] watchers the Guard watchers in the block
185
+ # @param [Array<String>] files the TypeScript files
186
+ # @param [Hash] options the options for the execution
187
+ # @option options [String] :output the output directory
188
+ # @option options [Boolean] :shallow do not create nested directories
189
+ #
190
+ def detect_nested_directories(watchers, files, options)
191
+ return { options[:output] => files } if options[:shallow]
192
+
193
+ directories = { }
194
+
195
+ watchers.product(files).each do |watcher, file|
196
+ if matches = file.match(watcher.pattern)
197
+ if options[:output]
198
+ target = matches[1] ? File.join(options[:output], File.dirname(matches[1])).gsub(/\/\.$/, '') : options[:output] || File.dirname(file)
199
+ else
200
+ target = File.dirname(file)
201
+ end
202
+ if directories[target]
203
+ directories[target] << file
204
+ else
205
+ directories[target] = [file]
206
+ end
207
+ end
208
+ end
209
+
210
+ directories
211
+ end
212
+
213
+ # Writes console and system notifications about the result of the compilation.
214
+ #
215
+ # @param [Array<String>] changed_files the changed JavaScript files
216
+ # @param [Array<String>] errors the error messages
217
+ # @param [Hash] options the options for the execution
218
+ # @option options [Boolean] :hide_success hide success message notification
219
+ # @option options [Boolean] :noop do not generate an output file
220
+ #
221
+ def notify_result(changed_files, errors, options = { })
222
+ if !errors.empty?
223
+ self.last_run_failed = true
224
+ Formatter.notify(errors.join("\n"), :title => 'TypeScript results', :image => :failed, :priority => 2)
225
+ elsif !options[:hide_success] || last_run_failed
226
+ self.last_run_failed = false
227
+ message = "Successfully #{ options[:noop] ? 'verified' : 'generated' } #{ changed_files.join(', ') }"
228
+ Formatter.success(message)
229
+ Formatter.notify(message, :title => 'TypeScript results')
230
+ end
231
+ end
232
+
233
+ end
234
+ end
235
+ end
236
+ end
@@ -0,0 +1 @@
1
+ guard 'typescript', :input => 'app/assets/javascripts'
@@ -0,0 +1,6 @@
1
+ module Guard
2
+ module TypeScriptVersion
3
+ # Guard::TypeScript version that is used for the Gem specification
4
+ VERSION = '0.1.0'
5
+ end
6
+ end
@@ -0,0 +1,81 @@
1
+ require 'guard'
2
+ require 'guard/guard'
3
+ require 'guard/watcher'
4
+
5
+ module Guard
6
+ # The TypeScript guard that gets notifications about the following
7
+ # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_change`.
8
+ #
9
+ class TypeScript < Guard
10
+ autoload :Formatter, 'guard/typescript/formatter'
11
+ autoload :Inspector, 'guard/typescript/inspector'
12
+ autoload :Runner, 'guard/typescript/runner'
13
+
14
+ DEFAULT_OPTIONS = {
15
+ :shallow => false,
16
+ :hide_success => false,
17
+ :error_to_js => false,
18
+ :all_on_start => false,
19
+ :source_map => false
20
+ }
21
+
22
+ # Initialize Guard::TypeScript.
23
+ #
24
+ # @param [Array<Guard::Watcher>] watchers the watchers in the Guard block
25
+ # @param [Hash] options the options for the Guard
26
+ # @option options [String] :input the input directory
27
+ # @option options [String] :output the output directory
28
+ # @option options [Boolean] :shallow do not create nested directories
29
+ # @option options [Boolean] :hide_success hide success message notification
30
+ # @option options [Boolean] :all_on_start generate all JavaScripts files on start
31
+ # @option options [Boolean] :source_map generate the source map files
32
+ #
33
+ def initialize(watchers = [], options = {})
34
+ watchers = [] if !watchers
35
+ defaults = DEFAULT_OPTIONS.clone
36
+
37
+ if options[:input]
38
+ defaults.merge!({ :output => options[:input] })
39
+ watchers << ::Guard::Watcher.new(%r{^#{ options[:input] }/(.+\.(?:ts))$})
40
+ end
41
+
42
+ super(watchers, defaults.merge(options))
43
+ end
44
+
45
+ # Gets called once when Guard starts.
46
+ #
47
+ # @raise [:task_has_failed] when stop has failed
48
+ #
49
+ def start
50
+ run_all if options[:all_on_start]
51
+ end
52
+
53
+ # Gets called when all files should be regenerated.
54
+ #
55
+ # @raise [:task_has_failed] when stop has failed
56
+ #
57
+ def run_all
58
+ run_on_modifications(Watcher.match_files(self, Dir.glob('**{,/*/**}/*.ts')))
59
+ end
60
+
61
+ # Gets called when watched paths and files have changes.
62
+ #
63
+ # @param [Array<String>] paths the changed paths and files
64
+ # @raise [:task_has_failed] when stop has failed
65
+ #
66
+ def run_on_modifications(paths)
67
+ changed_files, success = Runner.run(Inspector.clean(paths), watchers, options)
68
+
69
+ throw :task_has_failed unless success
70
+ end
71
+
72
+ # Called on file(s) deletions that the Guard watches.
73
+ #
74
+ # @param [Array<String>] paths the deleted files or paths
75
+ # @raise [:task_has_failed] when run_on_change has failed
76
+ #
77
+ def run_on_removals(paths)
78
+ Runner.remove(Inspector.clean(paths, :missing_ok => true), watchers, options)
79
+ end
80
+ end
81
+ end
metadata ADDED
@@ -0,0 +1,123 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-typescript
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Payton Yao
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2014-10-12 00:00:00 +08:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: guard
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 1
30
+ - 0
31
+ version: 1.1.0
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: ruby-typescript
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ - 1
44
+ - 0
45
+ version: 0.1.0
46
+ type: :runtime
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: bundler
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ segments:
56
+ - 0
57
+ version: "0"
58
+ type: :development
59
+ version_requirements: *id003
60
+ - !ruby/object:Gem::Dependency
61
+ name: rspec
62
+ prerelease: false
63
+ requirement: &id004 !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
70
+ type: :development
71
+ version_requirements: *id004
72
+ description: Guard::TypeScript automatically generates JavaScripts from your TypeScripts
73
+ email:
74
+ - payton.yao@gmail.com
75
+ executables: []
76
+
77
+ extensions: []
78
+
79
+ extra_rdoc_files: []
80
+
81
+ files:
82
+ - lib/guard/typescript/formatter.rb
83
+ - lib/guard/typescript/inspector.rb
84
+ - lib/guard/typescript/runner.rb
85
+ - lib/guard/typescript/templates/Guardfile
86
+ - lib/guard/typescript/version.rb
87
+ - lib/guard/typescript.rb
88
+ - LICENSE
89
+ - README.md
90
+ has_rdoc: true
91
+ homepage: http://github.com/jabbawookiees/guard-typescript
92
+ licenses:
93
+ - MIT
94
+ post_install_message:
95
+ rdoc_options: []
96
+
97
+ require_paths:
98
+ - lib
99
+ required_ruby_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ required_rubygems_version: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ segments:
111
+ - 1
112
+ - 3
113
+ - 6
114
+ version: 1.3.6
115
+ requirements: []
116
+
117
+ rubyforge_project: guard-typescript
118
+ rubygems_version: 1.3.6
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Guard gem for TypeScript
122
+ test_files: []
123
+