spark_engine 1.0.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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/CODE_OF_CONDUCT.md +49 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +34 -0
  7. data/Rakefile +2 -0
  8. data/bin/spark +99 -0
  9. data/lib/spark_engine/assets.rb +8 -0
  10. data/lib/spark_engine/command/help.rb +86 -0
  11. data/lib/spark_engine/command/npm.rb +62 -0
  12. data/lib/spark_engine/command.rb +156 -0
  13. data/lib/spark_engine/config_data.rb +29 -0
  14. data/lib/spark_engine/helpers/asset_helpers.rb +66 -0
  15. data/lib/spark_engine/helpers/layout_helpers.rb +21 -0
  16. data/lib/spark_engine/middleware.rb +72 -0
  17. data/lib/spark_engine/plugin/assets/asset.rb +163 -0
  18. data/lib/spark_engine/plugin/assets/javascripts.rb +83 -0
  19. data/lib/spark_engine/plugin/assets/stylesheets.rb +88 -0
  20. data/lib/spark_engine/plugin/assets/svgs.rb +79 -0
  21. data/lib/spark_engine/plugin.rb +191 -0
  22. data/lib/spark_engine/sass/engine.rb +21 -0
  23. data/lib/spark_engine/sass/importer.rb +103 -0
  24. data/lib/spark_engine/scaffold/gem/.gitignore +18 -0
  25. data/lib/spark_engine/scaffold/gem/app/assets/images/namespace/.keep +0 -0
  26. data/lib/spark_engine/scaffold/gem/app/assets/javascripts/namespace/engine.js +3 -0
  27. data/lib/spark_engine/scaffold/gem/app/assets/stylesheets/namespace/_index.scss +1 -0
  28. data/lib/spark_engine/scaffold/gem/app/assets/svgs/namespace/.keep +0 -0
  29. data/lib/spark_engine/scaffold/gem/app/helpers/namespace/application_helper.rb +4 -0
  30. data/lib/spark_engine/scaffold/gem/app/views/layouts/namespace/default.html.erb +18 -0
  31. data/lib/spark_engine/scaffold/gem/gem.gemspec +24 -0
  32. data/lib/spark_engine/scaffold/gem/lib/gem.rb +12 -0
  33. data/lib/spark_engine/scaffold/gem/site/app/assets/javascripts/application.js +1 -0
  34. data/lib/spark_engine/scaffold/gem/site/app/assets/stylesheets/application.scss +2 -0
  35. data/lib/spark_engine/scaffold/gem/site/app/controllers/docs_controller.rb +19 -0
  36. data/lib/spark_engine/scaffold/gem/site/app/views/docs/index.html.erb +1 -0
  37. data/lib/spark_engine/scaffold/gem/site/app/views/layouts/application.html.erb +4 -0
  38. data/lib/spark_engine/scaffold/gem/site/config/application.rb +18 -0
  39. data/lib/spark_engine/scaffold/gem/site/config/environments/development.rb +13 -0
  40. data/lib/spark_engine/scaffold/gem/site/config/routes.rb +3 -0
  41. data/lib/spark_engine/scaffold.rb +191 -0
  42. data/lib/spark_engine/version.rb +3 -0
  43. data/lib/spark_engine.rb +106 -0
  44. data/spark_engine.gemspec +31 -0
  45. metadata +234 -0
@@ -0,0 +1,103 @@
1
+ require 'sass'
2
+ require 'yaml'
3
+
4
+ module SparkEngine
5
+ module SassParser
6
+ extend self
7
+
8
+ # Global vars beginning with underscore will have their children promoted to globals
9
+ # and will be assigned without the underscore
10
+ #
11
+ # For example: _colors: { yellow: '#fco' }
12
+ # becomes: colors: { yellow: '#fco'}, yellow: '#fco'
13
+ #
14
+ #
15
+ def load_yaml(data)
16
+ promote_globals YAML.load(data)
17
+ end
18
+
19
+ def read_file(file)
20
+ IO.read(file)
21
+ end
22
+
23
+ def promote_globals( data )
24
+ data.keys.select{|k| k.start_with?('_') }.each do |key|
25
+ data[key.sub(/^_/,'')] = data[key]
26
+ data = data.delete(key).merge(data)
27
+ end
28
+
29
+ data
30
+ end
31
+
32
+ def expand_vars(file)
33
+ content = read_file(file)
34
+ file_data = load_yaml(content)
35
+
36
+ content = content.gsub(/\$(?<var>\w+)/) do
37
+ file_data[$~[:var]].inspect
38
+ end
39
+
40
+ load_yaml content
41
+ end
42
+
43
+ def parse(file)
44
+ expand_vars file
45
+ end
46
+ end
47
+
48
+ class Importer < Sass::Importers::Filesystem
49
+
50
+ def watched_file?(uri)
51
+ !!(uri =~ /\.yml$/ &&
52
+ uri.start_with?(root + File::SEPARATOR))
53
+ end
54
+
55
+ protected
56
+
57
+ def extensions
58
+ {'yml' => :scss}
59
+ end
60
+
61
+ def yaml?(name)
62
+ File.extname(name) == '.yml'
63
+ end
64
+
65
+ private
66
+
67
+ def _find(dir, name, options)
68
+ return unless yaml? name
69
+
70
+ full_filename, syntax = Sass::Util.destructure(find_real_file(dir, name, options))
71
+ return unless full_filename && File.readable?(full_filename)
72
+
73
+ yaml = SassParser.parse(full_filename)
74
+ variables = yaml.map { |key, value| "$#{key}: #{_convert_to_sass(value)};" }.join("\n")
75
+
76
+ Sass::Engine.new(variables, options.merge(
77
+ :filename => full_filename,
78
+ :importer => self,
79
+ :syntax => :scss
80
+ ))
81
+ end
82
+
83
+ def _convert_to_sass(item)
84
+ if item.is_a? Array
85
+ _make_list(item)
86
+ elsif item.is_a? Hash
87
+ _make_map(item)
88
+ else
89
+ item.to_s
90
+ end
91
+ end
92
+
93
+ def _make_list(item)
94
+ '(' + item.map { |i| _convert_to_sass(i) }.join(',') + ')'
95
+ end
96
+
97
+ def _make_map(item)
98
+ '(' + item.map {|key, value| key.to_s + ':' + _convert_to_sass(value) }.join(',') + ')'
99
+ end
100
+ end
101
+
102
+ end
103
+
@@ -0,0 +1,18 @@
1
+ .DS_Store
2
+ .bundle/
3
+ .vscode/
4
+ .yardoc
5
+ _yardoc/
6
+ coverage/
7
+ doc/
8
+ /spec/reports/
9
+ /tmp/
10
+ log/*.log
11
+ pkg/
12
+ node_modules
13
+ site/tmp/
14
+ /public/
15
+ .sass-cache
16
+ .esvg-cache
17
+ _icons.js
18
+ _esvg.js
@@ -0,0 +1,3 @@
1
+ // Require modules, add code, etc
2
+
3
+ window.<%= @engine %> = module.exports = {}
@@ -0,0 +1 @@
1
+ // Design System Stylesheets index
@@ -0,0 +1,4 @@
1
+ module <%= @plugin_module %>
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,18 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title><%= @plugin_module %></title>
5
+ <%%= csrf_meta_tags %>
6
+ <%%= asset_tags %>
7
+ <%%= yield :stylesheets %>
8
+ <%%= yield :head %>
9
+ </head>
10
+
11
+ <body>
12
+ <div class='site'>
13
+ <div class='page'><%%= yield %></div>
14
+ </div>
15
+ </body>
16
+ <%%= javascript_tag "<%= @engine %>" %>
17
+ <%%= yield :javascripts %>
18
+ </html>
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require "<%= @spec.name %>/version"
5
+
6
+ # Describe your gem and declare its dependencies:
7
+ Gem::Specification.new do |spec|
8
+ spec.name = "<%= @spec.name %>"
9
+ spec.version = <%= @gem_module %>::VERSION
10
+ spec.authors = <%= @spec.authors %>
11
+ spec.email = <%= @spec.email %>
12
+ spec.summary = "Summary of your gem."
13
+ spec.description = "Description of your gem (usually longer)."
14
+ spec.license = "<%= @spec.license %>"
15
+
16
+ spec.files = Dir["{app,lib,public,config}/**/*", "LICENSE.txt", "README.md"]
17
+ spec.require_paths = ["lib"]
18
+
19
+ spec.add_dependency "rails", ">= 4"
20
+ spec.add_runtime_dependency "spark_engine"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.12"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ end
@@ -0,0 +1,12 @@
1
+ require 'spark_engine'
2
+ require '<%= @gem %>/version'
3
+
4
+ module <%= @gem_module %>
5
+ class Plugin < SparkEngine::Plugin
6
+ end
7
+ end
8
+
9
+ SparkEngine.register(<%= @gem_module %>::Plugin, {
10
+ gem: '<%= @gem %>'<% unless @engine.nil? %>,
11
+ engine: '<%= @engine %>'<% end %>
12
+ })
@@ -0,0 +1,2 @@
1
+ /* *= require_self */
2
+ @import '<%= @engine %>/index';
@@ -0,0 +1,19 @@
1
+ class DocsController < ApplicationController
2
+ def show
3
+ page = params[:page]
4
+
5
+ %w(docs).each do | root_page |
6
+ if page.match(/#{root_page}\/?$/)
7
+ page = File.join(root_page, 'index')
8
+ end
9
+ end
10
+
11
+ if template_exists? page
12
+ render template: page
13
+ elsif template_exists? "docs/\#{page}"
14
+ render template: "docs/\#{page}"
15
+ else
16
+ render file: "404.html", status: :not_found
17
+ end
18
+ end
19
+ end
@@ -0,0 +1 @@
1
+ <h1><%= @plugin_module %> Documentation</h1>
@@ -0,0 +1,4 @@
1
+ <%%= render_layout '<%= namespace %>/default' do %>
2
+ <%%= stylesheets { stylesheet_link_tag('application') } %>
3
+ <%%= javascripts { javascript_include_tag('application') } %>
4
+ <%% end %>
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../boot', __FILE__)
2
+
3
+ require "rails"
4
+ # Pick the frameworks you want:
5
+ require "action_controller/railtie"
6
+ require "action_view/railtie"
7
+ require "sprockets/railtie"
8
+
9
+ # Require the gems listed in Gemfile, including any gems
10
+ # you've limited to :test, :development, or :production.
11
+ Bundler.require(*Rails.groups)
12
+
13
+ require '<%= @gem %>'
14
+
15
+ module Site
16
+ class Application < SparkEngine::Application
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ Rails.application.configure do
2
+ config.cache_classes = false
3
+
4
+ # Do not eager load code on boot.
5
+ config.eager_load = false
6
+
7
+ # Show full error reports and disable caching.
8
+ config.consider_all_requests_local = true
9
+ config.action_controller.perform_caching = false
10
+
11
+ # Print deprecation notices to the Rails logger.
12
+ config.active_support.deprecation = :log
13
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.routes.draw do
2
+ resources :docs, param: :page, path: ''
3
+ end
@@ -0,0 +1,191 @@
1
+ require 'fileutils'
2
+ require "spark_engine/command/npm"
3
+
4
+ module SparkEngine
5
+ class Scaffold
6
+ attr_reader :gem, :engine, :namespace, :plugin_module, :path, :gemspec_path
7
+
8
+ def initialize(options)
9
+ @cwd = File.expand_path(File.dirname(options[:name]))
10
+ @gem = underscorize(File.basename(options[:name]))
11
+ @engine = underscorize(options[:engine] || @gem)
12
+ @namespace = @engine
13
+ @plugin_module = modulize @engine
14
+ @gem_module = modulize @gem
15
+ @gem_temp = ".#{@gem}-temp"
16
+
17
+ FileUtils.mkdir_p @cwd
18
+
19
+ Dir.chdir @cwd do
20
+ puts "Creating new plugin #{@namespace}".bold
21
+
22
+ @gemspec_path = new_gem
23
+ @spec = Gem::Specification.load(@gemspec_path)
24
+ @path = File.expand_path(File.dirname(@gemspec_path))
25
+
26
+ engine_scaffold
27
+
28
+ bootstrap_gem
29
+ setup_package_json
30
+ update_git
31
+ end
32
+
33
+ post_install
34
+ end
35
+
36
+ # Create a new gem with Bundle's gem command
37
+ #
38
+ def new_gem
39
+ system "bundler gem #{gem}"
40
+ Dir.glob(File.join(gem, "/*.gemspec")).first
41
+ end
42
+
43
+ def setup_package_json
44
+ Dir.chdir path do
45
+ NPM.setup
46
+ end
47
+ end
48
+
49
+ def bootstrap_gem
50
+
51
+ # Remove bin
52
+ FileUtils.rm_rf(File.join(path, 'bin'))
53
+
54
+ scaffold_path = File.expand_path("scaffold/**/*", File.dirname(__FILE__))
55
+
56
+ Dir.glob(scaffold_path, File::FNM_DOTMATCH).select{|f| File.file? f}.each do |f|
57
+ write_template f.split(/spark_engine\/scaffold\//)[1]
58
+ end
59
+ end
60
+
61
+ # Create an Rails plugin engine for documentation site
62
+ def engine_scaffold
63
+ FileUtils.mkdir_p(@gem_temp)
64
+ Dir.chdir(@gem_temp) do
65
+ response = Open3.capture3("rails plugin new #{gem} --mountable --dummy-path=site --skip-test-unit")
66
+ if !response[1].empty?
67
+ puts response[1]
68
+ abort "FAILED: Please be sure you have the rails gem installed with `gem install rails`"
69
+ end
70
+
71
+ # Remove files and directories that are unnecessary for the
72
+ # light-weight Rails documentation site
73
+ remove = %w(mailers models assets channels jobs views).map{ |f| File.join('app', f) }
74
+ remove.concat %w(cable.yml storage.yml database.yml).map{ |f| File.join('config', f) }
75
+
76
+ remove.each { |f| FileUtils.rm_rf File.join(@gem, 'site', f), secure: true }
77
+ end
78
+
79
+
80
+ engine_copy
81
+ end
82
+
83
+ # Copy parts of the engine scaffold into site directory
84
+ def engine_copy
85
+ site_path = File.join path, 'site'
86
+ FileUtils.mkdir_p site_path
87
+
88
+ ## Copy Rails plugin files
89
+ Dir.chdir "#{@gem_temp}/#{gem}/site" do
90
+ %w(app config bin config.ru Rakefile public log).each do |item|
91
+ target = File.join site_path, item
92
+
93
+ FileUtils.cp_r item, target
94
+
95
+ action_log "create", target.sub(@cwd+'/','')
96
+ end
97
+
98
+ end
99
+
100
+ # Remove temp dir
101
+ FileUtils.rm_rf @gem_temp
102
+ end
103
+
104
+ def update_git
105
+ Dir.chdir gem do
106
+ system "git reset"
107
+ system "git add -A"
108
+ end
109
+ end
110
+
111
+ def write_template(template, target=nil)
112
+ template_path = File.expand_path("scaffold/#{template}", File.dirname(__FILE__))
113
+
114
+ # Extract file extension
115
+ ext = File.extname(template)
116
+
117
+ # Replace keywords with correct names (excluding file extensions)
118
+ target_path = template.sub(/#{ext}$/, '').gsub(/(gem|engine|namespace)/, {
119
+ 'gem' => @gem,
120
+ 'engine' => @engine,
121
+ 'namespace' => @namespace
122
+ }) + ext
123
+
124
+ write_file target_path, read_template(template_path)
125
+ end
126
+
127
+ def read_template(file_path)
128
+ contents = ''
129
+ File.open file_path do |f|
130
+ contents = ERB.new(f.read).result(binding)
131
+ end
132
+ contents
133
+ end
134
+
135
+ def write_file(paths, content='', mode='w')
136
+ paths = [paths].flatten
137
+ paths.each do |path|
138
+ if File.exist?(path)
139
+ type = 'update'
140
+ else
141
+ FileUtils.mkdir_p(File.dirname(path))
142
+ type = 'create'
143
+ end
144
+
145
+ File.open path, mode do |io|
146
+ io.write(content)
147
+ end
148
+
149
+ action_log(type, path)
150
+ end
151
+ end
152
+
153
+ def post_install
154
+ require 'pathname'
155
+
156
+ target = Pathname.new File.join(@cwd, @gem)
157
+ dir = target.relative_path_from Pathname.new(Dir.pwd)
158
+ victory = "#{@plugin_module} Design System created at #{dir}. Huzzah!"
159
+ dashes = ''
160
+ victory.size.times{ dashes += '-' }
161
+
162
+ puts "\n#{victory}\n#{dashes}".bold
163
+
164
+ puts "Install dependencies:"
165
+ puts " - cd #{dir}"
166
+ puts " - bundle"
167
+ puts " - yarn install (or npm install)\n\n"
168
+ puts "Then give it a spin.\n\n"
169
+ puts " spark build".bold + " - builds assets"
170
+ puts " spark server".bold + " - view documentation site in a server"
171
+ puts " spark help".bold + " - learn more…"
172
+ puts dashes + "\n\n"
173
+ end
174
+
175
+ def action_log(action, path)
176
+ puts action.rjust(12).colorize(:green).bold + " #{path}"
177
+ end
178
+
179
+ def modulize(input)
180
+ input.split('_').collect { |name|
181
+ (name =~ /[A-Z]/) ? name : name.capitalize
182
+ }.join
183
+ end
184
+
185
+ def underscorize(input)
186
+ input.gsub(/[A-Z]/) do |char|
187
+ '_'+char
188
+ end.sub(/^_/,'').downcase
189
+ end
190
+ end
191
+ end
@@ -0,0 +1,3 @@
1
+ module SparkEngine
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,106 @@
1
+ require "open3"
2
+ require "json"
3
+ require "colorize"
4
+
5
+ require "spark_engine/version"
6
+ require "spark_engine/plugin"
7
+ require "spark_engine/assets"
8
+ require "spark_engine/sass/engine"
9
+ require "spark_engine/sass/importer"
10
+ require "spark_engine/config_data"
11
+
12
+ module SparkEngine
13
+ extend self
14
+ attr_accessor :plugin
15
+ autoload :Application, "spark_engine/middleware"
16
+
17
+ def production?
18
+ ENV['CI'] || ENV['RAILS_ENV'] == 'production' || ( defined?(Command) && Command.production? )
19
+ end
20
+
21
+ def rails5?
22
+ Gem::Version.new(Rails.version) >= Gem::Version.new('5')
23
+ end
24
+
25
+ def plugin
26
+ @plugin
27
+ end
28
+
29
+ def config_data
30
+ SparkEngine::ConfigData.read(SparkEngine.plugin.root, Rails.root)
31
+ end
32
+
33
+ def register(plugin_module, options={}, &block)
34
+ @plugin = plugin_module.new(options)
35
+ if defined? Rails
36
+ @plugin.create_engine(&block)
37
+ patch_rails
38
+ end
39
+ end
40
+
41
+ def patch_rails
42
+ load_helpers
43
+ end
44
+
45
+ def load_helpers
46
+ require "spark_engine/helpers/asset_helpers"
47
+ require "spark_engine/helpers/layout_helpers"
48
+
49
+ SparkEngine::Helpers.constants.each do |c|
50
+ helper = SparkEngine::Helpers.const_get(c)
51
+ ActionView::Base.send :include, helper if defined? ActionView::Base
52
+ end
53
+ end
54
+
55
+ def at_rails_root?
56
+ File.exist?("bin/rails")
57
+ end
58
+
59
+ def plugin_gemspec
60
+ if gem_path
61
+ path = File.join(gem_path, "*.gemspec")
62
+ Dir[path].first
63
+ end
64
+ end
65
+
66
+ def plugin_spec
67
+ @plugin_spec ||= begin
68
+ if file = plugin_gemspec
69
+ spec = Gem::Specification.load(file)
70
+ spec if spec.name != 'spark_engine'
71
+ end
72
+ end
73
+ end
74
+
75
+ def load_plugin
76
+ plugin || if spec = plugin_spec
77
+ require spec.name unless spec.name == 'spark_engine'
78
+ return plugin
79
+ end
80
+ end
81
+
82
+ def at_gem_root?
83
+ !Dir['*.gemspec'].empty?
84
+ end
85
+
86
+ def gem_path
87
+ if at_gem_root?
88
+ Dir.pwd
89
+ elsif at_rails_root?
90
+ "../"
91
+ end
92
+ end
93
+
94
+ def rails_path(sub=nil)
95
+ path = if at_rails_root?
96
+ Dir.pwd
97
+ else
98
+ dir = Dir["**/bin/rails"]
99
+ if !dir.empty?
100
+ dir.first.split('/').first
101
+ end
102
+ end
103
+ path = File.join(path, sub) if sub
104
+ path
105
+ end
106
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ $:.push File.expand_path('../lib', __FILE__)
3
+ require 'spark_engine/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'spark_engine'
7
+ spec.version = SparkEngine::VERSION
8
+ spec.authors = ['Brandon Mathis']
9
+ spec.email = ['brandon@imathis.com']
10
+
11
+ spec.summary = %q{A design system framework for Rails (and humans).}
12
+ spec.homepage = 'https://github.com/imathis/spark'
13
+ spec.license = 'MIT'
14
+
15
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
16
+ spec.bindir = 'bin'
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.require_paths = ['lib']
19
+
20
+ spec.add_runtime_dependency 'sass', '~> 3.4'
21
+ spec.add_runtime_dependency 'esvg', '~> 4.2'
22
+ spec.add_runtime_dependency 'listen', '~> 3.0.0'
23
+ spec.add_runtime_dependency 'block_helpers', '~> 0.3'
24
+ spec.add_runtime_dependency 'colorize', '~> 0.8'
25
+ spec.add_runtime_dependency 'bundler', '~> 1.10'
26
+ spec.add_runtime_dependency 'autoprefixer-rails', '~> 9.0'
27
+ spec.add_runtime_dependency 'rails', '>= 4.2', '< 6'
28
+
29
+ spec.add_development_dependency 'rake', '~> 10.0'
30
+ spec.add_development_dependency 'pry-byebug'
31
+ end