easy_html_generator 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CONTRIBUTING.md +44 -0
- data/LICENSE +22 -0
- data/README.md +332 -0
- data/bin/ehg +52 -0
- data/lib/easy_html_generator.rb +100 -0
- data/lib/easy_html_generator/checksum.rb +39 -0
- data/lib/easy_html_generator/config.rb +147 -0
- data/lib/easy_html_generator/generator.rb +25 -0
- data/lib/easy_html_generator/generator/base.rb +83 -0
- data/lib/easy_html_generator/generator/combine.rb +28 -0
- data/lib/easy_html_generator/generator/compile/coffee.rb +30 -0
- data/lib/easy_html_generator/generator/compile/haml.rb +70 -0
- data/lib/easy_html_generator/generator/compile/haml/context.rb +52 -0
- data/lib/easy_html_generator/generator/compile/haml/helper/activesupport_override.rb +48 -0
- data/lib/easy_html_generator/generator/compile/haml/helper/asset_helper.rb +78 -0
- data/lib/easy_html_generator/generator/compile/haml/layout.rb +35 -0
- data/lib/easy_html_generator/generator/compile/sass.rb +47 -0
- data/lib/easy_html_generator/generator/copy.rb +44 -0
- data/lib/easy_html_generator/generator/delete.rb +20 -0
- data/lib/easy_html_generator/generator/minimize/css.rb +28 -0
- data/lib/easy_html_generator/generator/minimize/html.rb +32 -0
- data/lib/easy_html_generator/generator/minimize/images.rb +33 -0
- data/lib/easy_html_generator/generator/minimize/js.rb +28 -0
- data/lib/easy_html_generator/generator/service/analytics.rb +34 -0
- data/lib/easy_html_generator/generator/service/bower.rb +34 -0
- data/lib/easy_html_generator/generator/service/grunt.rb +24 -0
- data/lib/easy_html_generator/generator/structure.rb +20 -0
- data/lib/easy_html_generator/generators.rb +53 -0
- data/lib/easy_html_generator/project.rb +77 -0
- data/lib/easy_html_generator/rackapp.rb +67 -0
- data/lib/easy_html_generator/workspace.rb +59 -0
- data/src/demo/assets/images/demo.png +0 -0
- data/src/demo/assets/public/robots.txt +0 -0
- data/src/demo/assets/scripts/demo.js.coffee +1 -0
- data/src/demo/assets/scripts/plain.js +0 -0
- data/src/demo/assets/styles/app.css.sass +2 -0
- data/src/demo/assets/styles/plain.css +0 -0
- data/src/demo/lib/generators/project_generator.rb +12 -0
- data/src/demo/lib/helper/projecthelper.rb +5 -0
- data/src/demo/views/index.html.haml +1 -0
- data/src/demo/views/index/_lore_ipsum.haml +1 -0
- data/src/demo/views/layout.haml +8 -0
- data/src/demo/views/plain.html +0 -0
- data/src/shared/assets/images/shared.png +0 -0
- data/src/shared/assets/scripts/shared.js.coffee +1 -0
- data/src/shared/assets/scripts/shared.plain.js +0 -0
- data/src/shared/assets/styles/mixins/_arrows.sass +32 -0
- data/src/shared/assets/styles/mixins/_bootstrap-fixes.sass +12 -0
- data/src/shared/assets/styles/mixins/_buttons.sass +32 -0
- data/src/shared/assets/styles/mixins/_css3.sass +266 -0
- data/src/shared/assets/styles/mixins/_headjs-bootstrap-mediaqueries.sass +42 -0
- data/src/shared/assets/styles/mixins/_helper.sass +70 -0
- data/src/shared/assets/styles/mixins/_normalize.sass +340 -0
- data/src/shared/assets/styles/mixins/_reset.sass +46 -0
- data/src/shared/lib/generators/shared_generator.rb +12 -0
- data/src/shared/lib/helper/shared_helper.rb +16 -0
- data/src/shared/project.yml +127 -0
- data/src/shared/views/404.yml +5 -0
- data/src/template/assets/public/robots.txt +0 -0
- data/src/template/assets/scripts/index.js.coffee +1 -0
- data/src/template/assets/styles/index.css.sass +2 -0
- data/src/template/lib/generators/project_generator.rb +12 -0
- data/src/template/lib/helper/project_helper.rb +5 -0
- data/src/template/project.yml +128 -0
- data/src/template/views/index.html.haml +4 -0
- data/src/template/views/index/_lore_ipsum.haml +2 -0
- data/src/template/views/layout.haml +9 -0
- metadata +402 -0
@@ -0,0 +1,100 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# add lib folder to paths
|
4
|
+
$LOAD_PATH.unshift File.dirname(__FILE__)
|
5
|
+
|
6
|
+
# just require bootsrap and it will be in the sass path
|
7
|
+
require 'bootstrap-sass'
|
8
|
+
require 'bundler'
|
9
|
+
require 'colorize'
|
10
|
+
require 'rack'
|
11
|
+
|
12
|
+
# main module loads projects and dispatches rack requests
|
13
|
+
module EasyHtmlGenerator
|
14
|
+
EHC_WORKSPACE_PATH =
|
15
|
+
File.expand_path File.join(File.dirname(__FILE__), '..')
|
16
|
+
|
17
|
+
EHC_SRC_PATH = File.join(EHC_WORKSPACE_PATH, 'src')
|
18
|
+
EHC_SHARED_PATH = File.join(EHC_SRC_PATH, 'shared')
|
19
|
+
EHC_SHARED_HELPER_PATH = File.join(EHC_SHARED_PATH, 'lib', 'helper')
|
20
|
+
EHC_SHARED_GENERATORS_PATH = File.join(EHC_SHARED_PATH, 'lib', 'generators')
|
21
|
+
EHC_SHARED_STYLES_PATH = File.join(EHC_SHARED_PATH, 'assets', 'styles')
|
22
|
+
|
23
|
+
WORKSPACE_PATH = Bundler.root
|
24
|
+
SRC_PATH = File.join(WORKSPACE_PATH, 'src')
|
25
|
+
DIST_PATH = File.join(WORKSPACE_PATH, 'dist')
|
26
|
+
SHARED_PATH = File.join(SRC_PATH, 'shared')
|
27
|
+
SHARED_HELPER_PATH = File.join(SHARED_PATH, 'lib', 'helper')
|
28
|
+
SHARED_GENERATORS_PATH = File.join(SHARED_PATH, 'lib', 'generators')
|
29
|
+
SHARED_STYLES_PATH = File.join(SHARED_PATH, 'assets', 'styles')
|
30
|
+
|
31
|
+
CREATE_ON_INIT = [
|
32
|
+
SRC_PATH,
|
33
|
+
DIST_PATH
|
34
|
+
]
|
35
|
+
|
36
|
+
COPY_ON_INIT = {
|
37
|
+
EHC_SHARED_PATH => SHARED_PATH,
|
38
|
+
"#{EHC_SRC_PATH}/template" => "#{SRC_PATH}/demo"
|
39
|
+
}
|
40
|
+
|
41
|
+
Dir[File.dirname(__FILE__) + '/easy_html_generator/*.rb']
|
42
|
+
.each { |file| require file }
|
43
|
+
|
44
|
+
def self.projects
|
45
|
+
Workspace.projects
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.dispatch(request)
|
49
|
+
path = request.env['REQUEST_PATH'] || request.env['PATH_INFO']
|
50
|
+
cleaned_path = clean_path path
|
51
|
+
project_name = project_name_by_path path
|
52
|
+
|
53
|
+
project = Workspace.project_by_name project_name
|
54
|
+
|
55
|
+
return path unless project
|
56
|
+
|
57
|
+
project.generate if project.should_generate_for? cleaned_path
|
58
|
+
|
59
|
+
# return absolute dist path
|
60
|
+
File.join(project.dist_path, cleaned_path)
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.project_name_by_path(path)
|
64
|
+
path = path.slice(1..-1) if path.start_with? '/'
|
65
|
+
path = path.split('/').first if path.include? '/'
|
66
|
+
path
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.clean_path(path)
|
70
|
+
path = path.slice(1..-1) if path.start_with? '/'
|
71
|
+
path.sub!("#{project_name_by_path(path)}/", '')
|
72
|
+
path
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.generate_all
|
76
|
+
Workspace.projects.each(&:generate)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.generate_project(project)
|
80
|
+
Workspace.projects[project].generate
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.start_server(host, port)
|
84
|
+
app = Rack::Builder.new do
|
85
|
+
use Rack::Reloader, 0
|
86
|
+
use Rack::ContentLength
|
87
|
+
use Rack::AbstractFormat
|
88
|
+
use Rack::Deflater
|
89
|
+
use Rack::ETag
|
90
|
+
|
91
|
+
run EasyHtmlGenerator::Rackapp
|
92
|
+
end
|
93
|
+
|
94
|
+
config = { app: app,
|
95
|
+
Host: host,
|
96
|
+
Port: port}
|
97
|
+
|
98
|
+
Rack::Server.start config
|
99
|
+
end
|
100
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'digest/md5'
|
3
|
+
|
4
|
+
# this class handles file checksums
|
5
|
+
class EasyHtmlGenerator::Checksum
|
6
|
+
@file_checksums = {}
|
7
|
+
|
8
|
+
def self.checksum(input)
|
9
|
+
Digest::MD5.hexdigest(input)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.file_checksum(file)
|
13
|
+
checksum(File.read(file))
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.file_changed?(file, context = '')
|
17
|
+
key = build_key(file, context)
|
18
|
+
|
19
|
+
return true unless @file_checksums.key? key
|
20
|
+
|
21
|
+
@file_checksums[key] != file_checksum(file)
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.store_file(file, context = '')
|
25
|
+
key = build_key(file, context)
|
26
|
+
|
27
|
+
@file_checksums[key] = file_checksum(file)
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.invalidate_file(file, context = '')
|
31
|
+
key = build_key(file, context)
|
32
|
+
|
33
|
+
@file_checksums.delete(key)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.build_key(file, context = '')
|
37
|
+
"#{context}.#{file}"
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,147 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
# this class loads a yml file, symbolizes the keys and make the hash
|
5
|
+
# accessable via object attributes
|
6
|
+
class EasyHtmlGenerator::Config
|
7
|
+
def self.from_file(path)
|
8
|
+
return unless File.exist? path
|
9
|
+
|
10
|
+
ConfigHash.new YAML.load(File.open(path))
|
11
|
+
end
|
12
|
+
|
13
|
+
# symbolizes the keys and makes the hash accessable via object attributes
|
14
|
+
class ConfigHash < Hash
|
15
|
+
def initialize(hash = nil)
|
16
|
+
super
|
17
|
+
|
18
|
+
return unless hash
|
19
|
+
|
20
|
+
hash = self.class.symbolize_keys hash
|
21
|
+
hash.each { |k, v| self[k] = v }
|
22
|
+
end
|
23
|
+
|
24
|
+
def method_missing(name, *args)
|
25
|
+
# setter
|
26
|
+
if /^(\w+)=$/ =~ name
|
27
|
+
self[Regexp.last_match(1).to_sym] = args[0]
|
28
|
+
# getter
|
29
|
+
else
|
30
|
+
return super.method_missing name unless key? name
|
31
|
+
end
|
32
|
+
|
33
|
+
self[name]
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.symbolize_keys(obj)
|
37
|
+
case obj
|
38
|
+
when Array
|
39
|
+
obj.inject([]) do |res, val|
|
40
|
+
res << case val
|
41
|
+
when Hash, Array
|
42
|
+
symbolize_keys(val)
|
43
|
+
else
|
44
|
+
val
|
45
|
+
end
|
46
|
+
res
|
47
|
+
end
|
48
|
+
when Hash
|
49
|
+
obj.inject(ConfigHash.new) do |res, (key, val)|
|
50
|
+
nkey = case key
|
51
|
+
when String
|
52
|
+
key.to_sym
|
53
|
+
else
|
54
|
+
key
|
55
|
+
end
|
56
|
+
nval = case val
|
57
|
+
when Hash, Array
|
58
|
+
symbolize_keys(val)
|
59
|
+
else
|
60
|
+
val
|
61
|
+
end
|
62
|
+
res[nkey] = nval
|
63
|
+
res
|
64
|
+
end
|
65
|
+
else
|
66
|
+
obj
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# class EasyHtmlGenerator::Config
|
73
|
+
# def self.from_file(path)
|
74
|
+
# return unless File.exist? path
|
75
|
+
#
|
76
|
+
# ConfigHash.new YAML.load(File.open(path))
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# # symbolizes the keys and makes the hash accessable via object attributes
|
80
|
+
# class ConfigHash < Hash
|
81
|
+
# def initialize(hash = nil)
|
82
|
+
# super
|
83
|
+
# return unless hash
|
84
|
+
#
|
85
|
+
# hash = self.class.symbolize_keys hash
|
86
|
+
# hash.each { |k, v| self[k] = v }
|
87
|
+
# end
|
88
|
+
#
|
89
|
+
# def method_missing(name, *args)
|
90
|
+
# # setter
|
91
|
+
# if /^(\w+)=$/ =~ name
|
92
|
+
# self[Regexp.last_match(1).to_sym] = args[0]
|
93
|
+
# # getter
|
94
|
+
# else
|
95
|
+
# return super.method_missing name unless key? name
|
96
|
+
# end
|
97
|
+
#
|
98
|
+
# self[name]
|
99
|
+
# end
|
100
|
+
#
|
101
|
+
# def self.symbolize_keys(obj)
|
102
|
+
# case obj
|
103
|
+
# when Array
|
104
|
+
# inject_array(obj)
|
105
|
+
# when Hash
|
106
|
+
# inject_hash(obj)
|
107
|
+
# else
|
108
|
+
# obj
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# def self.inject_array(obj)
|
113
|
+
# obj.each_with_object([]) do |res, val|
|
114
|
+
# res << case val
|
115
|
+
# when Hash, Array
|
116
|
+
# symbolize_keys(val)
|
117
|
+
# else
|
118
|
+
# val
|
119
|
+
# end
|
120
|
+
# res
|
121
|
+
# end
|
122
|
+
# end
|
123
|
+
#
|
124
|
+
# def self.inject_hash(obj)
|
125
|
+
# obj.each_with_object(ConfigHash.new) do |res, (key, val)|
|
126
|
+
# nkey = inject_hash_key key
|
127
|
+
# nval = inject_hash_value val
|
128
|
+
# res[nkey] = nval
|
129
|
+
# res
|
130
|
+
# end
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# def self.inject_hash_key(key)
|
134
|
+
# case key
|
135
|
+
# when String then return key.to_sym
|
136
|
+
# else return key
|
137
|
+
# end
|
138
|
+
# end
|
139
|
+
#
|
140
|
+
# def self.inject_hash_value(val)
|
141
|
+
# case val
|
142
|
+
# when Hash, Array then symbolize_keys(val)
|
143
|
+
# else val
|
144
|
+
# end
|
145
|
+
# end
|
146
|
+
# end
|
147
|
+
# end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# this is a module namespace wrapper
|
4
|
+
module EasyHtmlGenerator::Generator
|
5
|
+
Dir[File.dirname(__FILE__) + '/generator/*.rb']
|
6
|
+
.each { |file| require file }
|
7
|
+
|
8
|
+
# this is a wrapper module for generator services
|
9
|
+
module Service
|
10
|
+
Dir[File.dirname(__FILE__) + '/generator/service/*.rb']
|
11
|
+
.each { |file| require file }
|
12
|
+
end
|
13
|
+
|
14
|
+
# this is a wrapper module for compiling generators
|
15
|
+
module Compile
|
16
|
+
Dir[File.dirname(__FILE__) + '/generator/compile/*.rb']
|
17
|
+
.each { |file| require file }
|
18
|
+
end
|
19
|
+
|
20
|
+
# this is a wrapper module for minimizing generators
|
21
|
+
module Minimize
|
22
|
+
Dir[File.dirname(__FILE__) + '/generator/minimize/*.rb']
|
23
|
+
.each { |file| require file }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'colorize'
|
3
|
+
require 'fileutils'
|
4
|
+
require 'easy_html_generator/generators'
|
5
|
+
|
6
|
+
# this is the generator base class
|
7
|
+
class EasyHtmlGenerator::Generator::Base
|
8
|
+
attr_reader :config
|
9
|
+
|
10
|
+
def initialize(project, config)
|
11
|
+
@project = project
|
12
|
+
@config = config
|
13
|
+
end
|
14
|
+
|
15
|
+
def src_path
|
16
|
+
"#{@project.src_path}/#{@config.src}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def dest_path
|
20
|
+
"#{@project.dist_path}/#{@config.dest}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def log_running
|
24
|
+
log "#{self.class.name.yellow}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate
|
28
|
+
return unless @config.enabled
|
29
|
+
|
30
|
+
log_running
|
31
|
+
|
32
|
+
selector = File.join(src_path, @config.selector)
|
33
|
+
|
34
|
+
FileUtils.mkdir_p dest_path
|
35
|
+
|
36
|
+
walk_files(selector) do |i, o|
|
37
|
+
next unless should_do_file? i
|
38
|
+
|
39
|
+
do_file(i, o)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def walk_files(selector)
|
44
|
+
Dir[selector].each do |input_file|
|
45
|
+
output_file = input_to_output_file(input_file)
|
46
|
+
|
47
|
+
yield(input_file, output_file)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def should_do_file?(i)
|
52
|
+
EasyHtmlGenerator::Checksum.file_changed? i
|
53
|
+
end
|
54
|
+
|
55
|
+
def input_to_output_file(input_file)
|
56
|
+
input_file.sub(src_path, dest_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
def do_input(input, *_args)
|
60
|
+
input
|
61
|
+
end
|
62
|
+
|
63
|
+
def do_file(src, target, *args)
|
64
|
+
return unless File.exist?(src) && File.file?(src)
|
65
|
+
|
66
|
+
log "-> do_file #{src.sub(@project.src_path, '').green}"
|
67
|
+
|
68
|
+
FileUtils.mkdir_p File.dirname(target)
|
69
|
+
|
70
|
+
args.push target
|
71
|
+
i = File.read(src)
|
72
|
+
o = do_input(i, *args)
|
73
|
+
|
74
|
+
File.write(target, o)
|
75
|
+
|
76
|
+
EasyHtmlGenerator::Checksum.store_file(src)
|
77
|
+
end
|
78
|
+
|
79
|
+
def log(msg)
|
80
|
+
STDERR.puts " | #{msg.sub(@project.src_path, '')
|
81
|
+
.sub('EasyHtmlGenerator::', '')}"
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'fileutils'
|
3
|
+
require 'easy_html_generator/generator/base'
|
4
|
+
|
5
|
+
# this generator combines files in the dist folder
|
6
|
+
class EasyHtmlGenerator::Generator::Combine <
|
7
|
+
EasyHtmlGenerator::Generator::Base
|
8
|
+
|
9
|
+
def generate
|
10
|
+
return unless @config.enabled
|
11
|
+
|
12
|
+
log_running
|
13
|
+
|
14
|
+
@config.packages.each do |config|
|
15
|
+
do_config config
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def do_config(config)
|
20
|
+
o = ''
|
21
|
+
config.files.each do |file_pattern|
|
22
|
+
Dir[File.join(@project.dist_path, file_pattern)].each do |file|
|
23
|
+
o += File.read(file) + "\n"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
File.write(File.join(@project.dist_path, config.file), o)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'coffee_script'
|
3
|
+
require 'easy_html_generator/generator/base'
|
4
|
+
|
5
|
+
# this generator coffee sass files from src folder and copies them
|
6
|
+
# to the dist folder
|
7
|
+
class EasyHtmlGenerator::Generator::Compile::Coffee <
|
8
|
+
EasyHtmlGenerator::Generator::Base
|
9
|
+
|
10
|
+
def initialize(project, config)
|
11
|
+
super(project, config)
|
12
|
+
|
13
|
+
@config.src = project.config.paths.src.scripts
|
14
|
+
@config.dest = project.config.paths.dist.scripts
|
15
|
+
end
|
16
|
+
|
17
|
+
def do_input(input, src = 'inline')
|
18
|
+
result = CoffeeScript.compile input
|
19
|
+
|
20
|
+
return result unless @config.minimize
|
21
|
+
|
22
|
+
EasyHtmlGenerator::Generator::Minimize::Js.compress result
|
23
|
+
rescue StandardError => e
|
24
|
+
raise e, "#{e.message} in #{src} ", e.backtrace
|
25
|
+
end
|
26
|
+
|
27
|
+
def input_to_output_file(i)
|
28
|
+
super(i).gsub('.js.coffee', '.js')
|
29
|
+
end
|
30
|
+
end
|