cyborg 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,28 @@
1
+ module Cyborg
2
+ module Helpers
3
+ module LayoutHelper
4
+ def layout(name, options={}, &block)
5
+ layout = options.delete(:layout) || 'application'
6
+ yield
7
+ render template: "layouts/#{name}/#{layout}"
8
+ end
9
+
10
+ def javascripts(&block)
11
+ content_for :javascripts, &block
12
+ end
13
+
14
+ def stylesheets(&block)
15
+ content_for :stylesheets, &block
16
+ end
17
+
18
+ def main(options={}, &block)
19
+ content_for :main, &block
20
+ end
21
+
22
+ def sidebar(&block)
23
+ content_for :sidebar, &block
24
+ end
25
+ end
26
+ end
27
+ end
28
+
@@ -0,0 +1,18 @@
1
+ require 'rack/cors'
2
+
3
+ module Cyborg
4
+ class Application < Rails::Application
5
+ config.middleware.insert_before ActionDispatch::Static, Rack::Deflater
6
+
7
+ config.middleware.insert_before 0, "Rack::Cors", :debug => true, :logger => (-> { Rails.logger }) do
8
+ allow do
9
+ origins "*"
10
+ resource "*", {
11
+ :headers => :any,
12
+ :expose => ["Location"],
13
+ :methods => [:get, :post, :put, :patch, :delete, :options]
14
+ }
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,152 @@
1
+ module Cyborg
2
+ class Plugin
3
+ attr_reader :module_name, :gem, :engine,
4
+ :stylesheets, :javascripts, :svgs, :destination
5
+
6
+ def initialize(options)
7
+ @name = options.delete(:name)
8
+ @module_name = parent_module.name
9
+ @gem = Gem.loaded_specs[@name]
10
+ config(options)
11
+ expand_asset_paths
12
+
13
+ # Store the gem path for access later when overriding root
14
+ parent_module.instance_variable_set(:@gem_path, root)
15
+ add_assets
16
+
17
+ @engine = create_engine if defined?(Rails)
18
+ end
19
+
20
+ def create_engine
21
+ # Create a new Rails::Engine
22
+ return parent_module.const_set('Engine', Class.new(Rails::Engine) do
23
+ def get_plugin_path
24
+ parent = Object.const_get(self.class.to_s.split('::').first)
25
+ path = parent.instance_variable_get("@gem_path")
26
+ Pathname.new path
27
+ end
28
+
29
+ def config
30
+ @config ||= Rails::Engine::Configuration.new(get_plugin_path)
31
+ end
32
+
33
+ initializer "#{name.to_s.downcase}.static_assets" do |app|
34
+ app.middleware.insert_before(::ActionDispatch::Static, ::ActionDispatch::Static, "#{root}/public")
35
+ end
36
+ end)
37
+ end
38
+
39
+ def parent_module
40
+ Object.const_get(self.class.to_s.split('::').first)
41
+ end
42
+
43
+ def add_assets
44
+ @javascripts = Assets::Javascripts.new(self, paths[:javascripts])
45
+ @stylesheets = Assets::Stylesheets.new(self, paths[:stylesheets])
46
+ @svgs = Assets::Svgs.new(self, paths[:svgs])
47
+ end
48
+
49
+ def assets
50
+ [@svgs, @stylesheets, @javascripts]
51
+ end
52
+
53
+ def build
54
+ Command.from_root {
55
+ FileUtils.mkdir_p(File.join(destination, asset_root))
56
+ }
57
+ threads = []
58
+ assets.each do |asset|
59
+ threads << Thread.new { asset.build }
60
+ end
61
+
62
+ threads
63
+ end
64
+
65
+ def watch
66
+ assets.map(&:watch)
67
+ end
68
+
69
+ def config(options)
70
+ options = {
71
+ production_asset_root: "/assets/#{@name}",
72
+ asset_root: "/assets/#{@name}",
73
+ destination: "public/",
74
+ root: @gem.full_gem_path,
75
+ version: @gem.version.to_s,
76
+ paths: {
77
+ stylesheets: "app/assets/stylesheets/#{@name}",
78
+ javascripts: "app/assets/javascripts/#{@name}",
79
+ svgs: "app/assets/svgs/#{@name}",
80
+ }
81
+ }.merge(options)
82
+
83
+ options.each do |k,v|
84
+ set_instance(k.to_s,v)
85
+ end
86
+ end
87
+
88
+
89
+ def expand_asset_paths
90
+ @paths.each do |type, path|
91
+ @paths[type] = File.join(root, path)
92
+ end
93
+ @destination = File.join(root, @destination)
94
+ end
95
+
96
+ def asset_root
97
+ if Cyborg.production?
98
+ plugin.production_asset_root
99
+ else
100
+ plugin.asset_root
101
+ end
102
+ end
103
+
104
+ private
105
+
106
+ def asset_ext(klass)
107
+ klass.name.split('::').last.downcase
108
+ end
109
+
110
+ # Find files based on class type and
111
+ # return an array of Classes for each file
112
+ def add_files(klass)
113
+ ext = asset_ext klass
114
+ find_files(ext).map do |path|
115
+ klass.new(self, path)
116
+ end
117
+ end
118
+
119
+ def glob(asset_ext)
120
+
121
+ end
122
+
123
+ # Find files by class type and extension
124
+ def find_files(ext)
125
+
126
+ files = Dir[File.join(paths[ext.to_sym], asset_glob(ext))]
127
+
128
+ # Filter out partials
129
+ files.reject { |f| File.basename(f).start_with?('_') }
130
+ end
131
+
132
+ def asset_glob(type)
133
+ case type
134
+ when "sass"
135
+ "*.s[ca]ss"
136
+ else
137
+ "*.#{type}"
138
+ end
139
+ end
140
+
141
+
142
+ # Convert configuration into instance variables
143
+ def set_instance(name, value)
144
+ instance_variable_set("@#{name}", value)
145
+ instance_eval(<<-EOS, __FILE__, __LINE__ + 1)
146
+ def #{name}
147
+ @#{name}
148
+ end
149
+ EOS
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,93 @@
1
+ module Cyborg
2
+ module Assets
3
+ class AssetType
4
+ attr_reader :plugin, :base
5
+
6
+ def initialize(plugin, base)
7
+ @base = base
8
+ @plugin = plugin
9
+ end
10
+
11
+ def find_files
12
+ files = Dir[File.join(base, "*.#{ext}")]
13
+
14
+ # Filter out partials
15
+ files.reject { |f| File.basename(f).start_with?('_') }
16
+ end
17
+
18
+ def versioned(path)
19
+ File.basename(path).sub(/(\.\w+)$/, '-'+plugin.version+'\1')
20
+ end
21
+
22
+ def build_msg(file)
23
+ "Built: #{destination(file).sub(plugin.root+'/','')}"
24
+ end
25
+
26
+ # Determine if an NPM module is installed by checking paths with `npm ls`
27
+ # Returns path to binary if installed
28
+ def find_node_module(cmd)
29
+
30
+ response = Open3.capture3("npm ls #{cmd}")
31
+
32
+ # Look in local `./node_modules` path.
33
+ # Be sure stderr is empty (the second argument returned by capture3)
34
+ if response[1].empty?
35
+ "$(npm bin)/#{cmd}"
36
+
37
+ # Check global module path
38
+ elsif Open3.capture3("npm ls -g #{cmd}")[1].empty?
39
+ cmd
40
+ end
41
+ end
42
+
43
+ def npm_command(cmd)
44
+ cmd = cmd.split(' ')
45
+ path = find_node_module(cmd.shift)
46
+ if path
47
+ system "#{path} #{cmd.join(' ')}"
48
+ end
49
+ end
50
+
51
+ def destination(path)
52
+ File.join(plugin.destination, plugin.asset_root, versioned(path))
53
+ end
54
+
55
+ def url(path)
56
+ File.join(plugin.asset_root, versioned(path))
57
+ end
58
+
59
+ def urls
60
+ find_files.map{ |file| url(file) }
61
+ end
62
+
63
+ def watch
64
+ puts "Watching for changes to #{base.sub(plugin.root+'/', '')}..."
65
+
66
+ Thread.new {
67
+ listener = Listen.to(base) do |modified, added, removed|
68
+ change(modified, added, removed)
69
+ end
70
+
71
+ listener.start # not blocking
72
+ sleep
73
+ }
74
+ end
75
+
76
+ def change(modified, added, removed)
77
+ puts "Added: #{file_event(added)}" unless added.empty?
78
+ puts "Removed: #{file_event(removed)}" unless removed.empty?
79
+ puts "Modified: #{file_event(modified)}" unless modified.empty?
80
+
81
+ build
82
+ end
83
+
84
+ def file_event(files)
85
+ list = files.map { |f| f.sub(base+'/', '') }.join(" \n")
86
+ list = " \n#{files}" if 1 < files.size
87
+
88
+ list
89
+ end
90
+
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,21 @@
1
+ module Cyborg
2
+ module Assets
3
+ class Javascripts < AssetType
4
+ def ext
5
+ "js"
6
+ end
7
+
8
+ def build
9
+ if find_node_module "browserify"
10
+ find_files.each do |file|
11
+ dest = destination(file).sub(/\.js$/,'')
12
+ npm_command "browserify #{file} -t babelify --standalone #{plugin.module_name} -o #{dest}.js -d -p [ minifyify --map #{url(file)}.map.json --output #{dest}.map.json ]"
13
+ puts build_msg(file)
14
+ end
15
+ else
16
+ abort "JS BUILD FAILED: browserify NPM module not found.\n" << "Please add browserify to your package.json and run `npm install`"
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,54 @@
1
+ module Cyborg
2
+ module Assets
3
+ class Stylesheets < AssetType
4
+
5
+ def ext
6
+ "*[ca]ss"
7
+ end
8
+
9
+ def build(ext=nil)
10
+ files = find_files
11
+ files = files.reject {|f| !f.match(/\.#{ext}/) } if ext
12
+
13
+ files.each do |file|
14
+
15
+ if File.extname(file).match(/\.css/)
16
+ build_css(file)
17
+ elsif File.extname(file).match(/\.s[ca]ss/)
18
+ build_sass(file)
19
+ end
20
+
21
+ dest = destination(file)
22
+ npm_command "postcss --use autoprefixer #{dest} -o #{dest}"
23
+
24
+ puts build_msg(file)
25
+ end
26
+ end
27
+
28
+ def build_css(file)
29
+ system "cp #{file} #{destination(file)}"
30
+ end
31
+
32
+ def build_sass(file)
33
+ style = 'nested'
34
+ sourcemap = 'auto'
35
+
36
+ if Cyborg.production?
37
+ style = "compressed"
38
+ sourcemap = 'false'
39
+ end
40
+
41
+ dest = destination(file)
42
+
43
+ system "sass #{file}:#{dest} --style #{style} --sourcemap=#{sourcemap}"
44
+ end
45
+
46
+
47
+ # Convert extension
48
+ def versioned(file)
49
+ super(file.sub(/(\.css)?\.s[ca]ss$/i,'.css'))
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,35 @@
1
+ module Cyborg
2
+ module Assets
3
+ class Svgs < AssetType
4
+
5
+ def initialize(plugin, path)
6
+ require 'esvg'
7
+ @plugin = plugin
8
+ @base = path
9
+
10
+ return if find_files.empty?
11
+
12
+ @svg = Esvg::SVG.new({
13
+ config_file: File.join(plugin.root, 'esvg.yml'),
14
+ path: path,
15
+ tmp_path: File.join(Cyborg.rails_path, 'tmp/cache/assets'),
16
+ js_path: File.join(plugin.paths[:javascripts], '_svg.js'),
17
+ optimize: true
18
+ })
19
+ end
20
+
21
+ def ext
22
+ "svg"
23
+ end
24
+
25
+ def build
26
+ return if find_files.empty?
27
+
28
+ @svg.read_files
29
+ if write_path = @svg.write
30
+ puts "Built: #{write_path.sub(plugin.root+'/','')}"
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Cyborg
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,195 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cyborg
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Brandon Mathis
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-07-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sass
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: esvg
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 2.8.10
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 2.8.10
41
+ - !ruby/object:Gem::Dependency
42
+ name: listen
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: block_helpers
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.3.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.3.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: colorize
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rack-cors
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: bundler
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.11'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.11'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rake
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: '10.0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: '10.0'
139
+ description: Build style-guide plugins Rails (and humans).
140
+ email:
141
+ - brandon@imathis.com
142
+ executables:
143
+ - cyborg
144
+ extensions: []
145
+ extra_rdoc_files: []
146
+ files:
147
+ - ".gitignore"
148
+ - CODE_OF_CONDUCT.md
149
+ - Gemfile
150
+ - LICENSE.txt
151
+ - README.md
152
+ - Rakefile
153
+ - bin/cyborg
154
+ - cyborg.gemspec
155
+ - lib/cyborg.rb
156
+ - lib/cyborg/assets.rb
157
+ - lib/cyborg/command.rb
158
+ - lib/cyborg/command/compress.rb
159
+ - lib/cyborg/command/help.rb
160
+ - lib/cyborg/command/npm.rb
161
+ - lib/cyborg/command/scaffold.rb
162
+ - lib/cyborg/helpers/asset_helpers.rb
163
+ - lib/cyborg/helpers/layout_helpers.rb
164
+ - lib/cyborg/middleware.rb
165
+ - lib/cyborg/plugin.rb
166
+ - lib/cyborg/plugin/assets/asset.rb
167
+ - lib/cyborg/plugin/assets/javascripts.rb
168
+ - lib/cyborg/plugin/assets/stylesheets.rb
169
+ - lib/cyborg/plugin/assets/svgs.rb
170
+ - lib/cyborg/version.rb
171
+ homepage: https://github.com/compose-ui/cyborg
172
+ licenses:
173
+ - MIT
174
+ metadata: {}
175
+ post_install_message:
176
+ rdoc_options: []
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '0'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubyforge_project:
191
+ rubygems_version: 2.5.1
192
+ signing_key:
193
+ specification_version: 4
194
+ summary: Build style-guide plugins Rails (and humans).
195
+ test_files: []