cup 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,3 @@
1
1
  *.gem
2
2
  .bundle
3
- Gemfile.lock
4
3
  pkg/*
data/.pryrc ADDED
@@ -0,0 +1,9 @@
1
+ $:.push File.expand_path('../lib', __FILE__)
2
+ $:.push File.expand_path('../spec', __FILE__)
3
+
4
+ require 'ruby-debug'
5
+ require 'cup'
6
+
7
+ def reload!
8
+ load 'cup.rb'
9
+ end
data/.rdebugrc ADDED
File without changes
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile.lock ADDED
@@ -0,0 +1,115 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ cup (0.0.2)
5
+ activemodel
6
+ coffee-script
7
+ rake
8
+ sass
9
+ sinatra
10
+ slim
11
+ therubyracer
12
+ thor
13
+ uglifier
14
+ yard
15
+
16
+ GEM
17
+ remote: http://rubygems.org/
18
+ specs:
19
+ activemodel (3.1.1)
20
+ activesupport (= 3.1.1)
21
+ builder (~> 3.0.0)
22
+ i18n (~> 0.6)
23
+ activesupport (3.1.1)
24
+ multi_json (~> 1.0)
25
+ archive-tar-minitar (0.5.2)
26
+ backports (2.3.0)
27
+ builder (3.0.0)
28
+ coffee-script (2.2.0)
29
+ coffee-script-source
30
+ execjs
31
+ coffee-script-source (1.1.2)
32
+ columnize (0.3.4)
33
+ daemons (1.1.4)
34
+ diff-lcs (1.1.3)
35
+ eventmachine (0.12.10)
36
+ execjs (1.2.9)
37
+ multi_json (~> 1.0)
38
+ i18n (0.6.0)
39
+ libv8 (3.3.10.2)
40
+ linecache19 (0.5.12)
41
+ ruby_core_source (>= 0.1.4)
42
+ monkey-lib (0.5.4)
43
+ backports
44
+ multi_json (1.0.3)
45
+ rack (1.3.3)
46
+ rack-protection (1.1.4)
47
+ rack
48
+ rack-test (0.6.1)
49
+ rack (>= 1.0)
50
+ rake (0.9.2)
51
+ rspec (2.6.0)
52
+ rspec-core (~> 2.6.0)
53
+ rspec-expectations (~> 2.6.0)
54
+ rspec-mocks (~> 2.6.0)
55
+ rspec-core (2.6.4)
56
+ rspec-expectations (2.6.0)
57
+ diff-lcs (~> 1.1.2)
58
+ rspec-mocks (2.6.0)
59
+ ruby-debug-base19 (0.11.25)
60
+ columnize (>= 0.3.1)
61
+ linecache19 (>= 0.5.11)
62
+ ruby_core_source (>= 0.1.4)
63
+ ruby-debug19 (0.11.6)
64
+ columnize (>= 0.3.1)
65
+ linecache19 (>= 0.5.11)
66
+ ruby-debug-base19 (>= 0.11.19)
67
+ ruby_core_source (0.1.5)
68
+ archive-tar-minitar (>= 0.5.2)
69
+ sass (3.1.10)
70
+ shoulda (2.11.3)
71
+ sinatra (1.3.0)
72
+ rack (~> 1.3)
73
+ rack-protection (~> 1.1)
74
+ tilt (~> 1.3)
75
+ sinatra-advanced-routes (0.5.1)
76
+ monkey-lib (~> 0.5.0)
77
+ sinatra (~> 1.0)
78
+ sinatra-sugar (~> 0.5.0)
79
+ sinatra-reloader (0.5.0)
80
+ sinatra (~> 1.0)
81
+ sinatra-advanced-routes (~> 0.5.0)
82
+ sinatra-sugar (0.5.1)
83
+ monkey-lib (~> 0.5.0)
84
+ sinatra (~> 1.0)
85
+ slim (1.0.3)
86
+ temple (~> 0.3.4)
87
+ tilt (~> 1.3.2)
88
+ statemachine (1.2.0)
89
+ temple (0.3.4)
90
+ therubyracer (0.9.8)
91
+ libv8 (~> 3.3.10)
92
+ thin (1.2.11)
93
+ daemons (>= 1.0.9)
94
+ eventmachine (>= 0.12.6)
95
+ rack (>= 1.0.0)
96
+ thor (0.14.6)
97
+ tilt (1.3.3)
98
+ uglifier (1.0.3)
99
+ execjs (>= 0.3.0)
100
+ multi_json (>= 1.0.2)
101
+ yard (0.7.2)
102
+
103
+ PLATFORMS
104
+ ruby
105
+
106
+ DEPENDENCIES
107
+ cup!
108
+ rack (= 1.3.3)
109
+ rack-test
110
+ rspec
111
+ ruby-debug19
112
+ shoulda
113
+ sinatra-reloader
114
+ statemachine
115
+ thin
data/README.md CHANGED
@@ -1,6 +1,86 @@
1
1
  Cup
2
2
  ===
3
3
 
4
- ## Creating a new javascript library
4
+ ## From ruby:
5
+
6
+ Cup.build
7
+ Cup.cup_name
8
+ Cup.minified
9
+ Cup.concatenated
10
+ Cup.version
11
+
12
+
13
+ ## CLI helper output
14
+
15
+ * INSERT HERE
16
+
17
+
18
+ ## Features
19
+
20
+
21
+ * Automatically includes javascripts, easy DSL for customizing their order
22
+ >>>> but NOT from inside spec/visuals1
23
+
24
+ * can uglify your project `cup build`
25
+ ** concatenates lib**/*.js and src/**/*.js into unminified and minified outputs in ./build
26
+
27
+ * `cup serve`
28
+ ** landing page for all serve capabilities
29
+ ** serve specs in concatenated and debug modes
30
+ ** serve visual spec index and serve spec/visual/**/*.spec.erb
31
+ ** includes all css files in every request
32
+ ** sinatra server extendable by add `server do <sinatra endpoints> end` to the Cupfile
33
+
34
+ @pages ||= {
35
+ :root => Page.new.tap do |page|
36
+ page.path = '/'
37
+ page.name = 'root'
38
+ page.template = :root
39
+ page.description = 'List of available pages'
40
+ end,
41
+ :debug => Page.new.tap do |page|
42
+ page.path = '/debug'
43
+ page.name = 'debug'
44
+ page.template = :debug
45
+ page.description = 'Headed page with lib and src javascript included'
46
+ end,
47
+ :empty => Page.new.tap do |page|
48
+ page.path = '/empty'
49
+ page.name = 'empty'
50
+ page.template = :debug
51
+ page.options[:layout] = false
52
+ page.description = 'Totally blank page with lib and src javascript included'
53
+ end,
54
+ :spec => Page.new.tap do |page|
55
+ page.path = '/spec'
56
+ page.name = 'specs'
57
+ page.template = :spec
58
+ page.options[:javascripts_scheme] = :spec
59
+ page.description = 'Run Jasmine specs on lib and src'
60
+ end,
61
+ :spec_concatenated => Page.new.tap do |page|
62
+ page.path = '/spec/concatenated'
63
+ page.name = 'specs on build output'
64
+ page.template = :spec
65
+ page.options[:javascripts_scheme] = :spec_concatenated
66
+ page.description = 'Run Jasmine specs on the build output'
67
+ end,
68
+ :spec_minified => Page.new.tap do |page|
69
+ page.path = '/spec/minified'
70
+ page.name = 'specs on minified build output'
71
+ page.template = :spec
72
+ page.options[:javascripts_scheme] = :spec_minified
73
+ page.description = 'Run Jasmine specs on minified build output'
74
+ end,
75
+ :spec_visual => Page.new.tap do |page|
76
+ page.path = '/spec/visual'
77
+ page.name = 'visual specs'
78
+ page.template = :spec
79
+ page.description = 'View available visual specs'
80
+ end
81
+ }
82
+
83
+ * uglified options overridable in Cupfile
84
+ before_build and after_build hooks are available too
85
+ * requires git
5
86
 
6
- `cup <name>`
data/Rakefile CHANGED
@@ -1,3 +1 @@
1
- require 'bundler/gem_tasks'
2
- require 'versionify'
3
- Versionify.install_rake_tasks
1
+ require 'bundler/gem_tasks'
data/TODO ADDED
@@ -0,0 +1,13 @@
1
+ > RUN every command line task
2
+ > VISIT every server page
3
+
4
+ >> rebuild superview, js-core-ext (rename to js-core-ext)
5
+
6
+ > INSPECT concatenated and minified output
7
+
8
+ > README
9
+ ---- Later ----
10
+
11
+ Rails app integration
12
+ * integrate with the jasmine-rails gem to run specs on the command line
13
+ * integrate with the asset pipeline
data/bin/cup CHANGED
@@ -1,19 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- require 'thor'
3
- require 'cup'
4
2
 
5
- class CupCli < Thor
6
-
7
- desc "create NAME", "Creates a new project structure with the specified name. Can also be called like: cup <name> [options]"
8
- method_option 'no-jquery'
9
- def create(name)
10
- puts "create: #{name}"
11
- end
12
-
13
- def method_missing (*params)
14
- params.length == 1 ? create(*params) : super
15
- end
16
-
17
- end
18
-
19
- CupCli.start
3
+ require 'cup/command_line'
4
+ Cup::CommandLine.start
data/cup.gemspec CHANGED
@@ -1,26 +1,42 @@
1
1
  # -*- encoding: utf-8 -*-
2
- #$:.push File.expand_path('../lib', __FILE__)
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'cup/version'
3
4
 
4
5
  Gem::Specification.new do |s|
5
6
  s.name = 'cup'
6
- s.version = '0.0.1' #Versionify.version
7
+ s.version = Cup::VERSION
7
8
  s.authors = ['Sam Taylor']
8
9
  s.email = ['sjltaylor@gmail.com']
9
10
  s.homepage = ''
10
11
  s.summary = 'ruby based tools for developing javascript libraries'
11
12
  # s.description = %q{TODO: Write a gem description}
12
-
13
- s.add_dependency 'rake'
14
- s.add_dependency 'sinatra'
15
- s.add_dependency 'versionify'
16
- s.add_dependency 'uglifier'
17
- s.add_dependency 'therubyracer'
18
- s.add_dependency 'thor'
19
-
13
+
14
+
20
15
  s.rubyforge_project = 'cup'
21
-
16
+
22
17
  s.files = `git ls-files`.split("\n")
23
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
19
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
20
  s.require_paths = ['lib']
21
+
22
+ s.add_runtime_dependency 'thor'
23
+ s.add_runtime_dependency 'activemodel'
24
+ s.add_runtime_dependency 'rake'
25
+ s.add_runtime_dependency 'therubyracer'
26
+ s.add_runtime_dependency 'uglifier'
27
+ s.add_runtime_dependency 'sinatra'
28
+ s.add_runtime_dependency 'slim'
29
+ s.add_runtime_dependency 'sass'
30
+ s.add_runtime_dependency 'coffee-script'
31
+ s.add_runtime_dependency 'yard'
32
+
33
+ s.add_development_dependency 'ruby-debug19'
34
+ s.add_development_dependency 'rspec'
35
+ s.add_development_dependency 'shoulda'
36
+ s.add_development_dependency 'statemachine'
37
+ s.add_development_dependency 'rack', '=1.3.3'
38
+ s.add_development_dependency 'rack-test'
39
+ s.add_development_dependency 'thin'
40
+ s.add_development_dependency 'sinatra-reloader'
41
+
26
42
  end
@@ -0,0 +1,29 @@
1
+ /*
2
+
3
+ These jasmine matchers are included by default when a project is created with cup.
4
+
5
+ */
6
+ beforeEach(function() {
7
+ this.addMatchers({
8
+ toBeAFunction: function() {
9
+ return typeof this.actual === 'function';
10
+ },
11
+ toBeInstanceOf: function (ctor) {
12
+ return this.actual instanceof ctor;
13
+ },
14
+ toContain: function (a) {
15
+ return this.actual.contains(a);
16
+ },
17
+ toBeEmpty: function () {
18
+ return this.actual.isEmpty();
19
+ },
20
+ toThrowAnError: function () {
21
+ try {
22
+ this.actual()
23
+ } catch (e) {
24
+ return e instanceof Error;
25
+ }
26
+ return false;
27
+ }
28
+ });
29
+ });
@@ -0,0 +1,127 @@
1
+ require 'uglifier'
2
+ require 'cup/noop_shell'
3
+
4
+ module Cup
5
+ class Builder
6
+ extend FileUtils
7
+
8
+ attr_reader :directory
9
+
10
+ def initialize directory
11
+ @directory = directory
12
+ @before_build_enabled = true
13
+ @after_build_enabled = true
14
+ end
15
+
16
+ def build *params
17
+ cupfile.before_build.call
18
+ concatenated = concatenate *params
19
+ minified = minify *params
20
+ cupfile.after_build.call
21
+ {
22
+ :concatenated => concatenated,
23
+ :minified => minified
24
+ }
25
+ end
26
+
27
+ def build! *params
28
+ cupfile.before_build.call
29
+ concatenated = concatenate! *params
30
+ minified = minify! *params
31
+ cupfile.after_build.call
32
+ {
33
+ :concatenated => concatenated,
34
+ :minified => minified
35
+ }
36
+ end
37
+
38
+ def concatenate *params
39
+ {:status => :ok, :output => (concatenate! *params)}
40
+ rescue Exception => e
41
+ {:status => :failed, :exception => e}
42
+ end
43
+
44
+ def minify *params
45
+ {:status => :ok, :output => (minify! *params)}
46
+ rescue Exception => e
47
+ {:status => :failed, :exception => e}
48
+ end
49
+
50
+ def concatenate!(options = {})
51
+ process(options, :concatenated) do |input_file_content|
52
+ input_file_content
53
+ end
54
+ end
55
+
56
+ def minify!(options = {})
57
+ uglifier_options = uglifier_defaults.merge directory.cupfile.uglifier_options
58
+
59
+ process(options, :minified) do |input_file_content|
60
+ Uglifier.compile input_file_content, uglifier_options
61
+ end
62
+ end
63
+
64
+ private
65
+
66
+ def process(options, output_file)
67
+
68
+ relative_output_file = directory.send output_file, :relative => true
69
+ output_file = directory.send output_file
70
+
71
+ options = default_options.merge options
72
+ cli = options[:cli]
73
+
74
+ build_directory = "#{directory.path.to_s}/build"
75
+ mkdir build_directory unless Dir.exists?(build_directory)
76
+ file = File.open(output_file, 'w')
77
+
78
+ file.write(license_header)
79
+
80
+ input_files.each do |input_file|
81
+ file.write(';')
82
+ file.write(yield File.read(input_file))
83
+ file.write(';')
84
+ end
85
+
86
+ cli.say("#{relative_output_file}: #{file.pos} bytes written.", :green)
87
+
88
+ file.close
89
+
90
+ File.read(output_file)
91
+ end
92
+ def cupfile
93
+ directory.cupfile
94
+ end
95
+ def default_options
96
+ { :cli => NoopShell }
97
+ end
98
+ def license_header
99
+ license = File.read(directory.cupfile.license) rescue nil
100
+ license.nil? ? '' : "/*\n#{license}\n*/"
101
+ end
102
+ def input_files
103
+ directory.javascripts :build_input
104
+ end
105
+ def uglifier_defaults
106
+ {
107
+ :mangle => true, # Mangle variables names
108
+ :toplevel => false, # Mangle top-level variable names
109
+ :except => [], # Variable names to be excluded from mangling
110
+ :max_line_length => 32 * 1024, # Maximum line length
111
+ :squeeze => true, # Squeeze code resulting in smaller, but less-readable code
112
+ :seqs => true, # Reduce consecutive statements in blocks into single statement
113
+ :dead_code => true, # Remove dead code (e.g. after return)
114
+ :unsafe => false, # Optimizations known to be unsafe in some situations
115
+ :copyright => true, # Show copyright message
116
+ :beautify => false, # Output indented code
117
+ :beautify_options => {
118
+ :indent_level => 2,
119
+ :indent_start => 0,
120
+ :quote_keys => false,
121
+ :space_colon => 0,
122
+ :ascii_only => false
123
+ }
124
+ }
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,225 @@
1
+ require 'thor'
2
+ require 'pathname'
3
+ require 'cup'
4
+ require 'cup/builder'
5
+ require 'cup/directory'
6
+ require 'cup/server/app'
7
+
8
+ module Cup
9
+ class CommandLine < Thor
10
+
11
+ include Thor::Actions
12
+
13
+ class Helper
14
+
15
+ JasmineStandaloneDistributionURL = 'http://pivotal.github.com/jasmine/downloads/jasmine-standalone-1.1.0.zip'
16
+ JQueryURL = 'http://code.jquery.com/jquery.min.js'
17
+
18
+ attr_reader :root
19
+
20
+ def initialize (path)
21
+ @root = Pathname.new(path).expand_path
22
+ end
23
+
24
+ def cupfile
25
+ root + 'Cupfile'
26
+ end
27
+
28
+ def cupfile_default_content(name)
29
+ <<-CUPFILE
30
+ # This file describes the javascript project
31
+ # see: https://github.com/sjltaylor/cup
32
+ Cup.define do |cup|
33
+
34
+ name '#{name}'
35
+ version '0.0.1'
36
+ license 'license.txt'
37
+
38
+ javascripts do
39
+ vendor 'jasmine.js', :*
40
+ end
41
+
42
+ end
43
+ CUPFILE
44
+ end
45
+
46
+ def standard_directories
47
+ %w|src lib vendor spec spec/visual|.map {|dir| root + dir}
48
+ end
49
+
50
+ def jquery_file
51
+ root + 'vendor' + 'jquery.min.js'
52
+ end
53
+
54
+ def extra_matchers_file
55
+ root + 'vendor' + 'extra_matchers.js'
56
+ end
57
+
58
+ def rackup_file
59
+ root + 'config.ru'
60
+ end
61
+
62
+ def cupfile?
63
+ File.exists?(root + 'Cupfile')
64
+ end
65
+
66
+ def license_file
67
+ root + 'license.txt'
68
+ end
69
+
70
+ def get_jquery
71
+ jquery = `curl --silent #{JQueryURL}`
72
+ return jquery if $?.exitstatus == 0
73
+ end
74
+
75
+ def get_license
76
+ <<-LICENSE
77
+ Copyright (C) #{Time.now.year} by #{ENV['USER'] || 'THE_MAN'}
78
+
79
+ Permission is hereby granted, free of charge, to any person obtaining a copy
80
+ of this software and associated documentation files (the "Software"), to deal
81
+ in the Software without restriction, including without limitation the rights
82
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
83
+ copies of the Software, and to permit persons to whom the Software is
84
+ furnished to do so, subject to the following conditions:
85
+
86
+ The above copyright notice and this permission notice shall be included in
87
+ all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
90
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
91
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
92
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
93
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
94
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
95
+ THE SOFTWARE.
96
+ LICENSE
97
+ end
98
+
99
+ def get_extra_matchers
100
+ File.read(File.expand_path('../../../js/extra_matchers.js', __FILE__))
101
+ end
102
+
103
+ def download_jasmine
104
+
105
+ %x{
106
+ set -o errexit # exit if it hits the fan
107
+ set -o nounset # using unset variables is an error
108
+
109
+ cd #{root + 'vendor'}
110
+
111
+ curl --silent #{JasmineStandaloneDistributionURL} > jasmine.zip
112
+ unzip jasmine.zip -d jasmine
113
+
114
+ cd jasmine
115
+
116
+ cp `find . | grep -E '.*\.(css|js)'` ..
117
+
118
+ cd ..
119
+
120
+ rm -rf jasmine
121
+ rm jasmine.zip
122
+ }
123
+
124
+ $?.exitstatus == 0
125
+ end
126
+ end
127
+
128
+ desc "create NAME", "Creates a new directory structure with the specified name. Can also be called like: cup <name> [options]"
129
+ def create(name)
130
+
131
+ unless /^[\w-]+$/ =~ name
132
+ raise "#{name} is not a valid filename (letters, numbers, underscore and dashes only)"
133
+ end
134
+
135
+ helper = Helper.new(name)
136
+
137
+ if Dir.exists? helper.root
138
+ say_status :halted, "Cannot cup '#{name}'. A directory of that name already exists", :red
139
+ return
140
+ end
141
+
142
+ empty_directory helper.root
143
+ helper.standard_directories.each {|dir| empty_directory dir}
144
+
145
+ create_file helper.cupfile, helper.cupfile_default_content(name)
146
+
147
+ create_file helper.license_file, helper.get_license
148
+
149
+ jquery = helper.get_jquery
150
+
151
+ if jquery
152
+ say_status(:downloaded, "#{Helper::JasmineStandaloneDistributionURL}", :green)
153
+ create_file helper.jquery_file, jquery
154
+ else
155
+ say_status(:failed, "download #{Helper::JQueryURL}", :red)
156
+ end
157
+
158
+ if helper.download_jasmine
159
+ say_status(:downloaded, "#{Helper::JasmineStandaloneDistributionURL} and unpacked into vendor", :green)
160
+ else
161
+ say_status(:failed, "download/unpack #{Helper::JasmineStandaloneDistributionURL}", :red)
162
+ end
163
+
164
+ create_file helper.extra_matchers_file, helper.get_extra_matchers
165
+ end
166
+
167
+ desc "build", 'builds and minifies into ./build/'
168
+ def build
169
+ Cup.build! :cli => self
170
+ end
171
+
172
+ desc "concatenate", 'builds to STDOUT'
173
+ def concatenate
174
+ $stdout.write Cup.concatenate!
175
+ end
176
+
177
+ desc "minify", 'builds to STDOUT'
178
+ def minify
179
+ $stdout.write Cup.minify!
180
+ end
181
+
182
+ desc "server [PORT]", 'Starts a sinatra app which serves spec runners etc.'
183
+ def server(port=5555)
184
+
185
+ helper = pwd_helper
186
+
187
+ return no_cupfile unless helper.cupfile?
188
+
189
+ say(shell.set_color "cup server for '#{Cup.cup_name}' starting on port #{port}", :cyan, true)
190
+ Cup::Server::App.set :port => port
191
+ Cup::Server::App.run!
192
+ end
193
+
194
+ desc "version", 'The version of cup and the version of the Cup project in this directory if a Cupfile exists'
195
+ def version
196
+ say("#{Cup.cup_name} v#{Cup.version}", :cyan) if File.exist?('Cupfile')
197
+ say("cup v#{Cup::VERSION}")
198
+ end
199
+
200
+ desc 'rackup', 'Create a config.ru. Do this if you want to use powder'
201
+ def rackup
202
+
203
+ helper = pwd_helper
204
+
205
+ return no_cupfile unless helper.cupfile?
206
+
207
+ create_file helper.rackup_file, <<-CONFIG_RU
208
+ require 'rubygems' # for ruby 1.8.x
209
+ require 'rack'
210
+ require 'cup/server/app'
211
+
212
+ run Cup::Server::App
213
+ CONFIG_RU
214
+ end
215
+
216
+ private
217
+
218
+ def pwd_helper
219
+ Helper.new(Cup::Directory.current.path.to_s)
220
+ end
221
+ def no_cupfile
222
+ say("Cupfile not present, bailing...", :red)
223
+ end
224
+ end
225
+ end