front_end_tasks 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: 834da5210e7838434da6cc1676045148c99d0b73
4
+ data.tar.gz: b570713b3aa5a9ae092d9c0f571070b3eeb0dac4
5
+ SHA512:
6
+ metadata.gz: a46f36a77e4a7bc549420e0a932c45c4c4cc50d8146cf5a3895bb6cc189c1ac108861e0160b81720b817c6f7fd5891c74c02a390c715c1ca97a0d383b84ea09d
7
+ data.tar.gz: 3158193588e3bcbf14116078cfc2cf5f7d8e1e91c4e6891abf295161584b710d7f2c540675ef10ac4c9baa427972ad2c47f8f3f6e52f71da4e904bd454906297
data/.gitignore ADDED
@@ -0,0 +1,18 @@
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
+ build/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in front_end_tasks.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Mike Enriquez (http://enriquez.me)
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.
data/README.md ADDED
@@ -0,0 +1,187 @@
1
+ # Front End Tasks
2
+
3
+ Command line tool for client side web application development. Great for develoeprs who prefer to write plain html, css, and javascript that works without any special pre-processing. This tool helps optimize, lint, and test that code.
4
+
5
+ # Installation
6
+
7
+ ```bash
8
+ $ gem install front_end_tasks
9
+ ```
10
+
11
+ The `fe` command will be available after installing Front End Tasks.
12
+
13
+ # Usage
14
+
15
+ Front End Tasks can be used from the command line or scripted with Ruby.
16
+
17
+ ## build
18
+
19
+ Compiles the given html file by combining and minifying javascript and stylesheet tags according to speical html comments (see HTML Comments section).
20
+
21
+ ```bash
22
+ $ fe build path/to/public_dir path/to/public_dir/index.html
23
+ ```
24
+
25
+ ```ruby
26
+ FrontEndTasks.build('path/to/public_dir', './build', 'path/to/public_dir/index.html')
27
+ ```
28
+
29
+ ## server
30
+
31
+ Run a development server on localhost.
32
+
33
+ ```bash
34
+ $ fe server --public_dir app/
35
+ ```
36
+
37
+ ```ruby
38
+ FrontEndTasks.server(:public_dir => './app')
39
+ ```
40
+
41
+ ## lint
42
+
43
+ Run the given files through JSLint.
44
+
45
+ ```bash
46
+ $ fe lint app/js/file_to_lint.js app/js/another_file.js
47
+ ```
48
+
49
+ ```ruby
50
+ FrontEndTasks.lint('./app/js/file_to_lint.js', './app/js/another_file.js')
51
+ ```
52
+
53
+ ## spec
54
+
55
+ Run Jasmine specs
56
+
57
+ ```bash
58
+ $ fe spec --source_files app/js/post.js --spec_files spec/PostSpec.js
59
+ ```
60
+
61
+ ```ruby
62
+ FrontEndTasks.spec({
63
+ :source_files => ['app/js/post.js'],
64
+ :spec_files => ['spec/PostSpec.js']
65
+ })
66
+ ```
67
+
68
+ ## list_scripts
69
+
70
+ List the javascript files that are included in the html (script tags) or js (importScripts) file
71
+
72
+ ```bash
73
+ $ fe list_scripts ./app/index.html
74
+ ```
75
+
76
+ ```ruby
77
+ FrontEndTasks.list_scripts('./app/index.html')
78
+ ```
79
+
80
+ # HTML Comments
81
+
82
+ ## build:script
83
+
84
+ Combine and minify scripts. Takes an argument that specifies the resulting file. See the following example
85
+
86
+ ```html
87
+ <!-- build:script js/scripts.min.js -->
88
+ <script src="/js/app.js"></script>
89
+ <script src="/js/home.js"></script>
90
+ <!-- /build -->
91
+ ```
92
+
93
+ The above combine and minify app.js and home.js together into scripts.min.js
94
+
95
+ ```html
96
+ <script src="/js/scripts.min.js"></script>
97
+ ```
98
+
99
+ Note: Only script tags that reference local urls are allowed between build:script and /build html comments.
100
+
101
+ ## build:style
102
+
103
+ Similar to build:script, but for stylesheets
104
+
105
+ ```html
106
+ <!-- build:style css/styles.min.css -->
107
+ <link href="vendor/bootstrap-3.1.1-dist/css/bootstrap.css" rel="stylesheet">
108
+ <link href="css/app.css" rel="stylesheet">
109
+ <!-- /build -->
110
+ ```
111
+
112
+ The above becomes
113
+
114
+ ```html
115
+ <link href="css/styles.min.css" rel="stylesheet">
116
+ ```
117
+
118
+ Note: Only link tags that reference local urls are allowed between build:style and /build html comments.
119
+
120
+ # External References
121
+
122
+ The build command will find any references to other files in the project and include them in the resulting build.
123
+
124
+ ## Stylesheets
125
+
126
+ CSS Files may reference fonts, images, etc... by using `url(...)`.
127
+
128
+ The contents inside `url()` are flattened to the file's basename. For example:
129
+
130
+ ```css
131
+ @font-face {
132
+ src: url('../fonts/glyphicons-halflings-regular.eot');
133
+ }
134
+ ```
135
+
136
+ Turns into
137
+
138
+ ```css
139
+ @font-face {
140
+ src: url('glyphicons-halflings-regular.eot');
141
+ }
142
+ ```
143
+
144
+ The above font file will be moved into the same directory as the combined stylesheet (remember that file paths from stylesheets are relative to the location of the calling stylesheet).
145
+
146
+ Note: Since all the files references from stylesheets are placed in the same directory, the filenames must be unique.
147
+
148
+ ## Javascripts
149
+
150
+ Javascript files may have references to worker scripts. For example:
151
+
152
+ ```js
153
+ var worker = new Worker('/js/workers/worker.js')
154
+ ```
155
+
156
+ The worker script references are kept the same. The worker script is copied to the build with the same directory structure. Worker scripts are then processed by replacing `importScripts` calls.
157
+
158
+ ```js
159
+ importScripts('/js/workers/worker_helper.js')
160
+ ```
161
+
162
+ The above is replaced with the contents of the given file, then the whole worker script is minified.
163
+
164
+ # MIT License
165
+
166
+ Copyright (c) 2014 Mike Enriquez (http://enriquez.me)
167
+
168
+ MIT License
169
+
170
+ Permission is hereby granted, free of charge, to any person obtaining
171
+ a copy of this software and associated documentation files (the
172
+ "Software"), to deal in the Software without restriction, including
173
+ without limitation the rights to use, copy, modify, merge, publish,
174
+ distribute, sublicense, and/or sell copies of the Software, and to
175
+ permit persons to whom the Software is furnished to do so, subject to
176
+ the following conditions:
177
+
178
+ The above copyright notice and this permission notice shall be
179
+ included in all copies or substantial portions of the Software.
180
+
181
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
182
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
183
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
184
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
185
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
186
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
187
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/fe ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ require 'front_end_tasks/cli'
3
+
4
+ FrontEndTasks::CLI.start
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'front_end_tasks/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "front_end_tasks"
8
+ spec.version = FrontEndTasks::VERSION
9
+ spec.authors = ["Mike Enriquez"]
10
+ spec.email = ["mike@enriquez.me"]
11
+ spec.description = %q{Command line tool for client side web application development}
12
+ spec.summary = %q{Front End Tasks comes with everything you need to minify javascript, minify css, run tests, run lint, and run a development server.}
13
+ spec.homepage = ""
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 "thor", "~> 0.19.1"
25
+ spec.add_dependency "nokogiri", "~> 1.6.1"
26
+ spec.add_dependency "uglifier", "~> 2.5.0"
27
+ spec.add_dependency "yui-compressor", "~> 0.12.0"
28
+ spec.add_dependency "webrick", "~> 1.3.1"
29
+ spec.add_dependency "jshintrb", "~> 0.2.4"
30
+ spec.add_dependency "jasmine", "~> 2.0.0"
31
+ end
@@ -0,0 +1,42 @@
1
+ require "front_end_tasks/version"
2
+
3
+ require 'front_end_tasks/optimizer'
4
+ require 'front_end_tasks/server'
5
+ require 'front_end_tasks/lint'
6
+ require 'front_end_tasks/spec'
7
+ require 'front_end_tasks/documents'
8
+
9
+ module FrontEndTasks
10
+
11
+ def self.build(public_dir, build_dir, *files)
12
+ optimizer = Optimizer.new(public_dir, files)
13
+ optimizer.build_to(build_dir)
14
+ end
15
+
16
+ def self.server(options)
17
+ Server.start(options)
18
+ end
19
+
20
+ def self.lint(*files)
21
+ Lint.report(files)
22
+ end
23
+
24
+ def self.spec(options)
25
+ Spec.run(options)
26
+ end
27
+
28
+ def self.list_scripts(file, public_root = nil)
29
+ content = File.read(File.expand_path(file))
30
+ extension = File.extname(file).downcase
31
+ doc = nil
32
+
33
+ if extension == '.html'
34
+ doc = Documents::HtmlDocument.new(nil, content)
35
+ elsif extension == '.js'
36
+ doc = Documents::JsDocument.new(nil, content)
37
+ end
38
+
39
+ doc.included_scripts(public_root)
40
+ end
41
+
42
+ end
@@ -0,0 +1,45 @@
1
+ require 'thor'
2
+ require 'front_end_tasks'
3
+
4
+ module FrontEndTasks
5
+
6
+ class CLI < Thor
7
+
8
+ desc "build", "Builds the given files according to special build comments"
9
+ method_option :result, :default => File.expand_path('./build')
10
+ def build(public_dir, *files)
11
+ FrontEndTasks.build(public_dir, options[:result], *files)
12
+ end
13
+
14
+ desc "server", "Run a static site directory on localhost"
15
+ method_option :public_dir, :default => File.expand_path('./build')
16
+ method_option :port, :default => 8000
17
+ def server
18
+ FrontEndTasks.server(options)
19
+ end
20
+
21
+ desc "lint", "Run JSLint"
22
+ def lint(*files)
23
+ FrontEndTasks.lint(*files)
24
+ end
25
+
26
+ desc "spec", "Run Jasmine specs"
27
+ method_option :source_files, :type => :array
28
+ method_option :worker_file
29
+ method_option :public_root
30
+ method_option :helper_files, :type => :array, :default => []
31
+ method_option :spec_files, :type => :array
32
+ method_option :port, :default => 8001
33
+ def spec
34
+ FrontEndTasks.spec(options)
35
+ end
36
+
37
+ desc "list_scripts", "List dependent javascript files"
38
+ method_option :public_root
39
+ def list_scripts(file)
40
+ puts FrontEndTasks.list_scripts(file, options[:public_root])
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,8 @@
1
+ require 'front_end_tasks/documents/base_document'
2
+ require 'front_end_tasks/documents/asset_document'
3
+ require 'front_end_tasks/documents/css_document'
4
+ require 'front_end_tasks/documents/js_document'
5
+ require 'front_end_tasks/documents/html_document'
6
+
7
+ module FrontEndTasks::Documents
8
+ end
@@ -0,0 +1,15 @@
1
+ require 'front_end_tasks/documents/base_document'
2
+
3
+ module FrontEndTasks
4
+ module Documents
5
+ class AssetDocument < BaseDocument
6
+
7
+ def compile
8
+ {
9
+ @compiled_path => @content
10
+ }
11
+ end
12
+
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ module FrontEndTasks
2
+ module Documents
3
+ class BaseDocument
4
+
5
+ attr_accessor :compiled_path
6
+
7
+ def initialize(public_root, content)
8
+ @public_root = public_root
9
+ @content = content
10
+ end
11
+
12
+ def compile
13
+ raise NotImplementedError.new('Must override "compile" in subclass')
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ require 'yui/compressor'
2
+ require 'front_end_tasks/documents/base_document'
3
+ require 'front_end_tasks/documents/asset_document'
4
+
5
+ module FrontEndTasks
6
+ module Documents
7
+ class CssDocument < BaseDocument
8
+
9
+ def compile
10
+ compressor = YUI::CssCompressor.new
11
+ compiled_content = compressor.compress(@content)
12
+
13
+ { @compiled_path => compiled_content }
14
+ end
15
+
16
+ def self.find_and_update_url_references(css_root, new_root, content)
17
+ assets = []
18
+ updated_content = content
19
+
20
+ url_references = content.scan(/url\(\s?['"](.*?)['"]\s?\)/)
21
+ url_references.each do |url_reference|
22
+ url = url_reference[0].strip
23
+ filename = File.basename(url).split("?")[0].split("#")[0]
24
+ local_file_path = File.join(css_root, File.dirname(url), filename)
25
+ new_path = File.join(new_root, filename)
26
+
27
+ # flatten url to down to just basename (including ? and # junk)
28
+ updated_content.sub!(url, File.basename(url))
29
+
30
+ # get asset contents
31
+ asset = AssetDocument.new(css_root, File.read(local_file_path))
32
+ asset.compiled_path = new_path
33
+ assets << asset
34
+ end
35
+
36
+ [updated_content, assets]
37
+ end
38
+
39
+ end
40
+ end
41
+ end