cyborg 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +41 -0
- data/Rakefile +2 -0
- data/bin/cyborg +70 -0
- data/cyborg.gemspec +32 -0
- data/lib/cyborg.rb +125 -0
- data/lib/cyborg/assets.rb +8 -0
- data/lib/cyborg/command.rb +60 -0
- data/lib/cyborg/command/compress.rb +24 -0
- data/lib/cyborg/command/help.rb +50 -0
- data/lib/cyborg/command/npm.rb +77 -0
- data/lib/cyborg/command/scaffold.rb +281 -0
- data/lib/cyborg/helpers/asset_helpers.rb +32 -0
- data/lib/cyborg/helpers/layout_helpers.rb +28 -0
- data/lib/cyborg/middleware.rb +18 -0
- data/lib/cyborg/plugin.rb +152 -0
- data/lib/cyborg/plugin/assets/asset.rb +93 -0
- data/lib/cyborg/plugin/assets/javascripts.rb +21 -0
- data/lib/cyborg/plugin/assets/stylesheets.rb +54 -0
- data/lib/cyborg/plugin/assets/svgs.rb +35 -0
- data/lib/cyborg/version.rb +3 -0
- metadata +195 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Cyborg
|
2
|
+
module GZIP
|
3
|
+
ZIP_TYPES = /\.(?:css|html|js|otf|svg|txt|xml)$/
|
4
|
+
|
5
|
+
def compress(glob)
|
6
|
+
Dir["#{Cyborg.config[:paths][:output]}/#{glob}"].each do |f|
|
7
|
+
next unless f =~ ZIP_TYPES
|
8
|
+
|
9
|
+
mtime = File.mtime(f)
|
10
|
+
gz_file = "#{f}.gz"
|
11
|
+
next if File.exist?(gz_file) && File.mtime(gz_file) >= mtime
|
12
|
+
|
13
|
+
File.open(gz_file, "wb") do |dest|
|
14
|
+
gz = Zlib::GzipWriter.new(dest, Zlib::BEST_COMPRESSION)
|
15
|
+
gz.mtime = mtime.to_i
|
16
|
+
IO.copy_stream(open(f), gz)
|
17
|
+
gz.close
|
18
|
+
end
|
19
|
+
|
20
|
+
File.utime(mtime, mtime, gz_file)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Cyborg
|
2
|
+
module Help
|
3
|
+
extend self
|
4
|
+
|
5
|
+
def banner(command=nil)
|
6
|
+
if command.nil?
|
7
|
+
<<-HERE
|
8
|
+
Commands:
|
9
|
+
#{commands.values.join("\n ")}
|
10
|
+
|
11
|
+
For help with a specific command, run `cyborg help command`
|
12
|
+
|
13
|
+
Options:
|
14
|
+
HERE
|
15
|
+
elsif commands[command.to_sym]
|
16
|
+
"\nUsage: #{commands[command.to_sym]}\n\nOptions:\n"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def commands
|
21
|
+
{
|
22
|
+
init: init,
|
23
|
+
npm: npm,
|
24
|
+
build: build,
|
25
|
+
watch: watch,
|
26
|
+
help: help
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
def init
|
31
|
+
"cyborg init [path] # Write default config file"
|
32
|
+
end
|
33
|
+
|
34
|
+
def npm
|
35
|
+
"cyborg npm [path] # Add NPM dependencies (path: dir with package.json, defaults to '.')"
|
36
|
+
end
|
37
|
+
|
38
|
+
def build
|
39
|
+
"cyborg build [options] # Build assets"
|
40
|
+
end
|
41
|
+
|
42
|
+
def watch
|
43
|
+
"cyborg watch [options] # Build assets when files change"
|
44
|
+
end
|
45
|
+
|
46
|
+
def help
|
47
|
+
"cyborg help [command] # Show help for a specific command"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Cyborg
|
2
|
+
module NPM
|
3
|
+
extend self
|
4
|
+
|
5
|
+
require "yaml"
|
6
|
+
|
7
|
+
DEPENDENCIES = YAML.load %Q{
|
8
|
+
private: true
|
9
|
+
devDependencies:
|
10
|
+
autoprefixer: ^5.2.0
|
11
|
+
babelify: ^6.4.0
|
12
|
+
browserify: ^11.2.0
|
13
|
+
minifyify: ^7.3.2
|
14
|
+
postcss-cli: ^1.5.0
|
15
|
+
svgo: ^0.5.6
|
16
|
+
}
|
17
|
+
|
18
|
+
def setup
|
19
|
+
puts "\nInstalling npm dependencies…".bold
|
20
|
+
|
21
|
+
if File.exist?(package_path)
|
22
|
+
update_package_json
|
23
|
+
install
|
24
|
+
else
|
25
|
+
write_package_json(DEPENDENCIES)
|
26
|
+
install
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def install
|
31
|
+
system "npm install"
|
32
|
+
end
|
33
|
+
|
34
|
+
def package_path
|
35
|
+
File.join(Dir.pwd, 'package.json')
|
36
|
+
end
|
37
|
+
|
38
|
+
def node_dependencies
|
39
|
+
DEPENDENCIES['devDependencies'].map do |k,v|
|
40
|
+
"#{k}@\"#{v}\""
|
41
|
+
end.join(' ')
|
42
|
+
end
|
43
|
+
|
44
|
+
def write_package_json(contents)
|
45
|
+
File.open(package_path, 'w') do |io|
|
46
|
+
io.write(JSON.pretty_generate(contents))
|
47
|
+
end
|
48
|
+
|
49
|
+
puts "create".rjust(12).colorize(:green).bold + " #{package_path}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def read_package_json
|
53
|
+
JSON.parse File.read(package_path)
|
54
|
+
end
|
55
|
+
|
56
|
+
def update_package_json
|
57
|
+
package = read_package_json
|
58
|
+
package['dependencies'] ||= {}
|
59
|
+
package['devDependencies'] ||= {}
|
60
|
+
|
61
|
+
deps = DEPENDENCIES['devDependencies']
|
62
|
+
|
63
|
+
deps.keys.each do |dep|
|
64
|
+
d = deps[dep]
|
65
|
+
|
66
|
+
if package['devDependencies'][dep].nil? && package['dependencies'][dep].nil?
|
67
|
+
package['devDependencies'][dep] = d
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
package.delete('dependencies') if package['dependencies'].empty?
|
72
|
+
|
73
|
+
write_package_json(package)
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,281 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module Cyborg
|
4
|
+
class Scaffold
|
5
|
+
attr_reader :name, :spec, :path, :gemspec_path
|
6
|
+
|
7
|
+
def initialize(name)
|
8
|
+
@cwd = Dir.pwd
|
9
|
+
@name = name.downcase
|
10
|
+
@module_name = name.split('_').collect(&:capitalize).join
|
11
|
+
|
12
|
+
puts "Creating new plugin #{name}".bold
|
13
|
+
engine_site_scaffod
|
14
|
+
|
15
|
+
@gemspec_path = create_gem
|
16
|
+
@path = File.expand_path(File.dirname(@gemspec_path))
|
17
|
+
|
18
|
+
fix_gemspec_files
|
19
|
+
|
20
|
+
@spec = Gem::Specification.load(@gemspec_path)
|
21
|
+
|
22
|
+
bootstrap_gem
|
23
|
+
engine_app_scaffold
|
24
|
+
engine_copy
|
25
|
+
prepare_engine_site
|
26
|
+
install_npm_modules
|
27
|
+
update_git
|
28
|
+
end
|
29
|
+
|
30
|
+
# Create a new gem with Bundle's gem command
|
31
|
+
#
|
32
|
+
def create_gem
|
33
|
+
begin
|
34
|
+
require 'bundler'
|
35
|
+
require 'bundler/cli'
|
36
|
+
Bundler::CLI.start(['gem', name])
|
37
|
+
|
38
|
+
Dir.glob(File.join(name, "/*.gemspec")).first
|
39
|
+
|
40
|
+
rescue LoadError
|
41
|
+
raise "To use this feature you'll need to install the bundler gem with `gem install bundler`."
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def install_npm_modules
|
46
|
+
Dir.chdir path do
|
47
|
+
NPM.setup
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# First remove scaffold spec.files (which rely on git) to avoid errors
|
52
|
+
# when loading the spec
|
53
|
+
def fix_gemspec_files
|
54
|
+
gs = File.read(gemspec_path)
|
55
|
+
|
56
|
+
File.open(gemspec_path, 'w') do |io|
|
57
|
+
io.write gs.gsub(/^.+spec\.files.+$/,'')
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def bootstrap_gem
|
62
|
+
|
63
|
+
# Remove unnecessary bin dir
|
64
|
+
FileUtils.rm_rf(File.join(path, 'bin'))
|
65
|
+
|
66
|
+
# Simplify gempsec and set up to add assets properly
|
67
|
+
File.open(gemspec_path, 'w') do |io|
|
68
|
+
io.write gemspec
|
69
|
+
end
|
70
|
+
|
71
|
+
action_log "update", gemspec_path
|
72
|
+
|
73
|
+
File.open "#{name}/lib/#{name}.rb", 'w' do |io|
|
74
|
+
io.write %Q{require 'megatron'
|
75
|
+
require '#{name}/version'
|
76
|
+
|
77
|
+
module #{@module_name}
|
78
|
+
class Plugin < Cyborg::Plugin
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
Cyborg.register(#{@module_name}::Plugin, {
|
83
|
+
name: '#{name}'
|
84
|
+
})}
|
85
|
+
end
|
86
|
+
action_log "update", "#{name}/lib/#{name}.rb"
|
87
|
+
end
|
88
|
+
|
89
|
+
# Add engine's app assets and utilities
|
90
|
+
def engine_app_scaffold
|
91
|
+
|
92
|
+
# Add asset dirs
|
93
|
+
%w(images javascripts stylesheets svgs).each do |path|
|
94
|
+
path = "#{name}/app/assets/#{path}/#{name}"
|
95
|
+
FileUtils.mkdir_p path
|
96
|
+
FileUtils.touch File.join(path, '.keep')
|
97
|
+
action_log "create", path
|
98
|
+
end
|
99
|
+
|
100
|
+
# Add helper and layout dirs
|
101
|
+
%w(helpers views/layouts).each do |path|
|
102
|
+
path = "#{name}/app/#{path}/#{name}"
|
103
|
+
FileUtils.mkdir_p path
|
104
|
+
action_log "create", path
|
105
|
+
end
|
106
|
+
|
107
|
+
# Add an application helper
|
108
|
+
File.open("#{name}/app/helpers/#{name}/application_helper.rb", 'w') do |io|
|
109
|
+
io.write %Q{module #{@module_name}
|
110
|
+
module ApplicationHelper
|
111
|
+
end
|
112
|
+
end}
|
113
|
+
action_log "create", "#{name}/app/helpers/#{name}/application_helper.rb"
|
114
|
+
end
|
115
|
+
|
116
|
+
# Add an a base layout
|
117
|
+
File.open("#{name}/app/views/layouts/#{name}/application.html.erb", 'w') do |io|
|
118
|
+
io.write %Q{<!DOCTYPE html>
|
119
|
+
<html>
|
120
|
+
<head>
|
121
|
+
<title>#{@module_name}</title>
|
122
|
+
<%= csrf_meta_tags %>
|
123
|
+
<%= asset_tags %>
|
124
|
+
<%= yield :stylesheets %>
|
125
|
+
<%= yield :javascripts %>
|
126
|
+
<%= yield :head %>
|
127
|
+
</head>
|
128
|
+
<body>
|
129
|
+
|
130
|
+
<div class='site'>
|
131
|
+
<div class='page'><%=yield %></div>
|
132
|
+
</div>
|
133
|
+
</body>
|
134
|
+
</html>}
|
135
|
+
end
|
136
|
+
action_log "create", "#{name}/app/views/layouts/#{name}/application.html.erb"
|
137
|
+
|
138
|
+
File.open("#{name}/.gitignore", 'a') do |io|
|
139
|
+
io.write %Q{.DS_Store
|
140
|
+
log/*.log
|
141
|
+
pkg/
|
142
|
+
node_modules
|
143
|
+
site/log/*.log
|
144
|
+
site/tmp/
|
145
|
+
.sass-cache}
|
146
|
+
end
|
147
|
+
action_log "update", "#{name}/.gitignore"
|
148
|
+
end
|
149
|
+
|
150
|
+
def engine_site_scaffod
|
151
|
+
FileUtils.mkdir_p(".#{name}-tmp")
|
152
|
+
Dir.chdir ".#{name}-tmp" do
|
153
|
+
response = Open3.capture3("rails plugin new #{name} --mountable --dummy-path=site --skip-test-unit")
|
154
|
+
if !response[1].empty?
|
155
|
+
puts response[1]
|
156
|
+
abort "FAILED: Please be sure you have the rails gem installed with `gem install rails`"
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def engine_copy
|
162
|
+
site_path = File.join(path, 'site')
|
163
|
+
FileUtils.mkdir_p(site_path)
|
164
|
+
|
165
|
+
Dir.chdir ".#{name}-tmp/#{name}" do
|
166
|
+
%w(app config bin config.ru Rakefile public log).each do |item|
|
167
|
+
target = File.join(site_path, item)
|
168
|
+
|
169
|
+
FileUtils.cp_r(File.join('site', item), target)
|
170
|
+
action_log "create", target.sub(@cwd+'/','')
|
171
|
+
end
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
FileUtils.rm_rf(".#{name}-tmp")
|
176
|
+
%w(app/mailers app/models config/database.yml).each do |item|
|
177
|
+
FileUtils.rm_rf(File.join(site_path, item))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def prepare_engine_site
|
182
|
+
site_path = File.join(path, 'site')
|
183
|
+
|
184
|
+
File.open File.join(site_path, 'config/environments/development.rb'), 'w' do |io|
|
185
|
+
io.write %Q{Rails.application.configure do
|
186
|
+
config.cache_classes = false
|
187
|
+
|
188
|
+
# Do not eager load code on boot.
|
189
|
+
config.eager_load = false
|
190
|
+
|
191
|
+
# Show full error reports and disable caching.
|
192
|
+
config.consider_all_requests_local = true
|
193
|
+
config.action_controller.perform_caching = false
|
194
|
+
|
195
|
+
# Print deprecation notices to the Rails logger.
|
196
|
+
config.active_support.deprecation = :log
|
197
|
+
end
|
198
|
+
}
|
199
|
+
end
|
200
|
+
|
201
|
+
File.open File.join(site_path, 'config/application.rb'), 'w' do |io|
|
202
|
+
io.write %Q{require File.expand_path('../boot', __FILE__)
|
203
|
+
|
204
|
+
require "rails"
|
205
|
+
# Pick the frameworks you want:
|
206
|
+
require "action_controller/railtie"
|
207
|
+
require "action_view/railtie"
|
208
|
+
|
209
|
+
# Require the gems listed in Gemfile, including any gems
|
210
|
+
# you've limited to :test, :development, or :production.
|
211
|
+
Bundler.require(*Rails.groups)
|
212
|
+
|
213
|
+
module Site
|
214
|
+
class Application < Cyborg::Application
|
215
|
+
end
|
216
|
+
end}
|
217
|
+
end
|
218
|
+
|
219
|
+
File.open File.join(site_path, 'config/routes.rb'), 'w' do |io|
|
220
|
+
io.write %Q{Rails.application.routes.draw do
|
221
|
+
resources :docs, param: :page, path: ''
|
222
|
+
end}
|
223
|
+
end
|
224
|
+
|
225
|
+
File.open File.join(site_path, 'app/controllers/docs_controller.rb'), 'w' do |io|
|
226
|
+
io.write %Q{class DocsController < ApplicationController
|
227
|
+
def show
|
228
|
+
render action: "#\{params[:page]\}"
|
229
|
+
end
|
230
|
+
end}
|
231
|
+
end
|
232
|
+
|
233
|
+
File.open File.join(site_path, 'app/views/layouts/application.html.erb'), 'w' do |io|
|
234
|
+
io.write %Q{<%= layout '#{name}' do %>\n<% end %>}
|
235
|
+
end
|
236
|
+
FileUtils.mkdir_p File.join(site_path, 'app/views/docs')
|
237
|
+
File.open File.join(site_path, 'app/views/docs/index.html.erb'), 'w' do |io|
|
238
|
+
io.write %Q{<h1>#{@module_name} Documentaiton</h1>}
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
def update_git
|
243
|
+
Dir.chdir @name do
|
244
|
+
system "git reset"
|
245
|
+
system "git add -A"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
249
|
+
def gemspec
|
250
|
+
%Q{# coding: utf-8
|
251
|
+
$:.push File.expand_path("../lib", __FILE__)
|
252
|
+
|
253
|
+
require "#{spec.name}/version"
|
254
|
+
|
255
|
+
# Describe your gem and declare its dependencies:
|
256
|
+
Gem::Specification.new do |spec|
|
257
|
+
spec.name = "#{spec.name}"
|
258
|
+
spec.version = #{@module_name}::VERSION
|
259
|
+
spec.authors = #{spec.authors}
|
260
|
+
spec.email = #{spec.email}
|
261
|
+
spec.summary = "Summary of your gem."
|
262
|
+
spec.description = "Description of your gem (usually longer)."
|
263
|
+
spec.license = "#{spec.license}"
|
264
|
+
|
265
|
+
spec.files = Dir["{app,config,lib/public}/**/*", "LICENSE.txt", "README.md"]
|
266
|
+
spec.require_paths = ["lib"]
|
267
|
+
|
268
|
+
spec.add_dependency "rails", "~> #{`rails -v`.strip.split(' ').last}"
|
269
|
+
spec.add_runtime_dependency "megatron"
|
270
|
+
|
271
|
+
spec.add_development_dependency "bundler", "~> 1.12"
|
272
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
273
|
+
end
|
274
|
+
}
|
275
|
+
end
|
276
|
+
|
277
|
+
def action_log(action, path)
|
278
|
+
puts action.rjust(12).colorize(:green).bold + " #{path}"
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Cyborg
|
2
|
+
module Helpers
|
3
|
+
module AssetsHelper
|
4
|
+
|
5
|
+
def get_asset_path(asset)
|
6
|
+
host = Cyborg.production? ? ENV['ASSETS_CDN'] || config[:assets_cdn] : '/'
|
7
|
+
|
8
|
+
File.join(host, asset)
|
9
|
+
end
|
10
|
+
|
11
|
+
def asset_tags
|
12
|
+
tags = ''
|
13
|
+
|
14
|
+
Cyborg.plugins.each do |plugin|
|
15
|
+
plugin.javascripts.urls.each do |url|
|
16
|
+
tags += javascript_include_tag(url)
|
17
|
+
end
|
18
|
+
plugin.stylesheets.urls.each do |url|
|
19
|
+
tags += stylesheet_link_tag(url)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
tags.html_safe
|
24
|
+
end
|
25
|
+
|
26
|
+
def pin_tab_icon(path)
|
27
|
+
%Q{<link rel="mask-icon" mask href="#{path}" color="black">}.html_safe
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|