fronton 0.1.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f4ea27d21a7fcbac4a66a2266e4bd76851a8f21f
4
+ data.tar.gz: a14b250d931a46b335928e6546d0d1016ef6d59b
5
+ SHA512:
6
+ metadata.gz: 8b54192e91e2e0b9f7ffd1d3427311b3673b40d1665a8f348f04a06b33e68e4e642a94d128af3aa866f35c986fce697f6ede3b0389932036c10627ab60e9a3af
7
+ data.tar.gz: 2965585b4697e93a81b7deefa9e431cbcfab67133dc4e6592d9b24edec0510a0e8e90f08b4cb72b9d07ae780e35f9046c9a484ea194c589fca118ce02fe0fab9
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright © 2016 Javier Aranda
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # Fronton
2
+
3
+ A command-line tool for build frontend apps in Ruby.
4
+
5
+
6
+ ## Status
7
+
8
+ > **This project is still experimental, use with caution!**
9
+
10
+
11
+ ## Installation
12
+
13
+ ```
14
+ $ gem install fronton
15
+ ```
16
+
17
+ `TODO`: Write an advanced installation guide
18
+
19
+
20
+ ## Usage
21
+
22
+ `TODO`: Write usage instructions here
23
+
24
+
25
+ ## Testing
26
+
27
+ `TODO`: Write how to test
28
+
29
+
30
+ ## Contributing
31
+
32
+ Contributions are welcome, please follow [GitHub Flow](https://guides.github.com/introduction/flow/index.html)
33
+
34
+
35
+ ## Versioning
36
+
37
+ **fronton** uses [Semantic Versioning 2.0.0](http://semver.org)
38
+
39
+
40
+ ## License
41
+
42
+ Copyright © 2016 Javier Aranda. Released under [MIT](LICENSE.md) license.
data/bin/fronton ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+ $LOAD_PATH << File.expand_path('../../lib', __FILE__)
3
+ require 'fronton'
4
+
5
+ Fronton::CLI.start
data/fronton.gemspec ADDED
@@ -0,0 +1,34 @@
1
+ require_relative 'lib/fronton/version'
2
+ require 'date'
3
+
4
+ Gem::Specification.new do |spec|
5
+ #
6
+ ## INFORMATION
7
+ #
8
+ spec.name = 'fronton'
9
+ spec.version = Fronton.version
10
+ spec.summary = 'A command-line tool for build frontend apps in Ruby'
11
+ spec.description = nil
12
+ spec.author = 'Javier Aranda'
13
+ spec.email = 'javier.aranda.varo@gmail.com'
14
+ spec.license = 'MIT'
15
+ spec.date = Date.today.strftime('%Y-%m-%d')
16
+ spec.homepage = 'https://github.com/javierav/fronton'
17
+
18
+ #
19
+ ## GEM
20
+ #
21
+ spec.bindir = 'bin'
22
+ spec.require_paths = %w(lib)
23
+ spec.files = `git ls-files -z -- lib bin template LICENSE README.md fronton.gemspec`.split("\x0")
24
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
25
+ spec.extra_rdoc_files = %w(README.md LICENSE)
26
+ spec.required_ruby_version = '~> 2.3'
27
+
28
+ #
29
+ ## DEPENDENCIES
30
+ #
31
+ spec.add_dependency 'thor', '~> 0.19', '>= 0.19.1'
32
+ spec.add_dependency 'rack', '~> 2.0', '>= 2.0.1'
33
+ spec.add_dependency 'sprockets', '~> 3.7'
34
+ end
@@ -0,0 +1,24 @@
1
+ module Fronton
2
+ class AssetsHelpers
3
+ def initialize(options = {})
4
+ @use_digest = options.fetch(:digest, false)
5
+ @prefix = options.fetch(:prefix, 'assets')
6
+ @manifest = options.fetch(:manifest)
7
+ end
8
+
9
+ def javascript_tag(name)
10
+ name = asset_path("#{name}.js")
11
+ %(<script src="#{name}"></script>\n)
12
+ end
13
+
14
+ def stylesheet_tag(name)
15
+ name = asset_path("#{name}.css")
16
+ %(<link href="#{name}" media="screen" rel="stylesheet" />\n)
17
+ end
18
+
19
+ def asset_path(name)
20
+ asset_name = @use_digest && @manifest.assets[name] ? @manifest.assets[name] : name
21
+ "#{@prefix}/#{asset_name}"
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,151 @@
1
+ require 'fileutils'
2
+ require 'rack'
3
+ require 'thor'
4
+ require 'fronton/config'
5
+ require 'fronton/html_server'
6
+
7
+ module Fronton
8
+ class CLI < Thor
9
+ include Thor::Actions
10
+
11
+ def self.source_root
12
+ File.expand_path('../../..', __FILE__)
13
+ end
14
+
15
+ no_commands do
16
+ def config
17
+ if !@config.is_a?(Fronton::Config) && @config.respond_to?(:call)
18
+ @config = @config.call
19
+ else
20
+ @config
21
+ end
22
+ end
23
+ end
24
+
25
+ def initialize(*args)
26
+ super(*args)
27
+ @config = -> { Fronton::Config.load! }
28
+ end
29
+
30
+ desc 'new APP_NAME', 'Creates new frontend app'
31
+ def new(name)
32
+ if Dir.exist? name
33
+ say_status 'create', "#{name} directory already exists. Abort!", :red
34
+ exit 1
35
+ else
36
+ directory 'template', name
37
+ end
38
+ end
39
+
40
+ desc 'server', 'Preview your app in browser'
41
+ method_option :port, type: :numeric, default: 3000, banner: 'PORT the server listen port'
42
+ def server # rubocop:disable Metrics/AbcSize
43
+ # install dependencies for rails assets
44
+ config.install_dependencies
45
+
46
+ # require dependencies for rails assets
47
+ config.require_dependencies
48
+
49
+ conf = config
50
+
51
+ app = Rack::Builder.new do
52
+ map('/assets') { run conf.environment }
53
+ map('/') { run Fronton::HTMLServer.new(config: conf) }
54
+ end
55
+
56
+ Rack::Server.start(
57
+ app: app,
58
+ environment: 'development',
59
+ Port: options[:port]
60
+ )
61
+ end
62
+
63
+ desc 'compile', 'Compiles assets using digest and minification'
64
+ def compile # rubocop:disable Metrics/AbcSize
65
+ # install dependencies for rails assets
66
+ config.install_dependencies
67
+
68
+ # require dependencies for rails assets
69
+ config.require_dependencies
70
+
71
+ # configure environment
72
+ if config.compressor_js
73
+ config.environment.js_compressor = config.compressor_js.to_sym
74
+ end
75
+
76
+ if config.compressor_css
77
+ config.environment.css_compressor = config.compressor_css.to_sym
78
+ end
79
+
80
+ # compile assets
81
+ config.manifest.compile(config.assets)
82
+
83
+ # compile html pages
84
+ config.pages.map(&:save)
85
+ end
86
+
87
+ desc 'clean', 'Remove old assets'
88
+ method_option :keep, type: :numeric, default: 2, banner: 'KEEP assets versions to keep'
89
+ def clean
90
+ config.manifest.clean(options[:keep])
91
+ end
92
+
93
+ desc 'clobber', 'Remove all assets'
94
+ def clobber
95
+ # assets
96
+ config.manifest.clobber
97
+
98
+ # html
99
+ FileUtils.rm Dir.glob(config.output.join('*.html'))
100
+ end
101
+
102
+ desc 'info', 'Information about project'
103
+ def info # rubocop:disable Metrics/AbcSize
104
+ say 'Dependencies', :bold
105
+
106
+ @dependencies = config.dependencies.map do |dep|
107
+ status = dep.available? ? 'Installed' : 'Not Installed'
108
+ [dep.name, dep.version, status]
109
+ end
110
+
111
+ print_table @dependencies
112
+
113
+ puts ''
114
+
115
+ say 'Assets Paths', :bold
116
+ config.assets_paths.each { |path| puts path.to_s }
117
+
118
+ puts ''
119
+
120
+ say 'Pages Paths', :bold
121
+ config.pages_paths.each { |path| puts path.to_s }
122
+
123
+ puts ''
124
+
125
+ say 'Sprockets Engines', :bold
126
+
127
+ @engines = config.environment.engines.map { |ext, klass| [ext, klass] }
128
+ print_table @engines
129
+
130
+ puts ''
131
+
132
+ say 'Compressors', :bold
133
+
134
+ @available_compressors = []
135
+ @used_compressors = [config.compressor_css.to_sym, config.compressor_js.to_sym]
136
+
137
+ config.environment.compressors.each do |mime, list|
138
+ list.each do |id, klass|
139
+ mark = @used_compressors.include?(id) ? '<--' : ''
140
+ @available_compressors << [mime, id, klass, mark]
141
+ end
142
+ end
143
+
144
+ print_table @available_compressors
145
+
146
+ puts ''
147
+
148
+ say "Powered by Fronton v#{Fronton.version} - https://github.com/javierav/fronton", :bold
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,128 @@
1
+ require 'pathname'
2
+ require 'logger'
3
+ require 'yaml'
4
+ require 'sprockets'
5
+ require 'fronton/dependency'
6
+
7
+ module Fronton
8
+ class Config
9
+ class YAMLNotFound < StandardError; end
10
+
11
+ def self.load!
12
+ file = Pathname.pwd.join('fronton.yml')
13
+
14
+ if file.exist?
15
+ self.new( YAML.load_file(file) )
16
+ else
17
+ raise YAMLNotFound, "File 'fronton.yml' not found in #{Dir.pwd}"
18
+ end
19
+ end
20
+
21
+ def initialize(parsed_yaml)
22
+ @config = parsed_yaml
23
+ @logger = Logger.new($stderr)
24
+ @logger.level = Logger::INFO
25
+ end
26
+
27
+ #
28
+ ## ACCESSORS
29
+ #
30
+
31
+ def assets
32
+ @assets ||= @config['assets'].is_a?(Array) ? @config['assets'] : []
33
+ end
34
+
35
+ def assets_paths
36
+ @assets_paths ||= begin
37
+ if @config['assets_paths'].is_a?(Array)
38
+ @config['assets_paths'].map { |p| working_dir.join(p) }
39
+ else
40
+ []
41
+ end
42
+ end
43
+ end
44
+
45
+ def output
46
+ @output ||= working_dir.join(@config['output'] || 'public')
47
+ end
48
+
49
+ def dependencies
50
+ @dependencies ||= begin
51
+ dep = @config['dependencies'].is_a?(Array) ? @config['dependencies'] : []
52
+
53
+ dep.map do |d|
54
+ Dependency.new(d.keys.first, d.values.first)
55
+ end
56
+ end
57
+ end
58
+
59
+ def pages
60
+ @pages ||= begin
61
+ pages = @config['pages'].is_a?(Array) ? @config['pages'] : []
62
+
63
+ pages.map do |page|
64
+ Page.new(page.keys.first, page.values.first, config: self)
65
+ end
66
+ end
67
+ end
68
+
69
+ def pages_paths
70
+ @pages_paths ||= begin
71
+ if @config['pages_paths'].is_a?(Array)
72
+ @config['pages_paths'].map { |p| working_dir.join(p) }
73
+ else
74
+ []
75
+ end
76
+ end
77
+ end
78
+
79
+ def compressor_js
80
+ @config['compressors'] && @config['compressors']['js']
81
+ end
82
+
83
+ def compressor_css
84
+ @config['compressors'] && @config['compressors']['css']
85
+ end
86
+
87
+ def environment
88
+ @environment ||= begin
89
+ env = Sprockets::Environment.new
90
+
91
+ # logger
92
+ env.logger = @logger
93
+
94
+ # fronton.yml assets paths
95
+ assets_paths.each { |path| env.append_path path }
96
+
97
+ # rails assets paths
98
+ if defined? RailsAssets
99
+ RailsAssets.load_paths.each { |path| env.append_path path }
100
+ end
101
+
102
+ env
103
+ end
104
+ end
105
+
106
+ def manifest
107
+ @manifest ||= Sprockets::Manifest.new environment, File.join(output, 'assets', 'manifest.json')
108
+ end
109
+
110
+ #
111
+ ## METHODS
112
+ #
113
+
114
+ def install_dependencies
115
+ dependencies.map(&:install_dependency)
116
+ end
117
+
118
+ def require_dependencies
119
+ dependencies.map(&:require_dependency)
120
+ end
121
+
122
+ private
123
+
124
+ def working_dir
125
+ Pathname.pwd
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,27 @@
1
+ module Fronton
2
+ class Dependency
3
+ attr_reader :name, :version
4
+
5
+ def initialize(name, version)
6
+ @name = name
7
+ @version = version
8
+ end
9
+
10
+ def available?
11
+ Gem::Specification.find_by_name(@name, @version) && true
12
+ rescue Gem::LoadError => _
13
+ false
14
+ end
15
+
16
+ def install_dependency
17
+ Gem.install @name, @version unless available?
18
+ end
19
+
20
+ def require_dependency
21
+ # activate gem
22
+ gem @name, @version
23
+ # require gem
24
+ require @name
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ require 'fronton/page'
2
+
3
+ module Fronton
4
+ class HTMLServer
5
+ def initialize(options = {})
6
+ @config = options.fetch(:config)
7
+ end
8
+
9
+ # Rack entrypoint
10
+ def call(env)
11
+ if page = requested_page(env) # rubocop:disable Lint/AssignmentInCondition
12
+
13
+ if page.exist?
14
+ render_page(page)
15
+ else
16
+ error_404
17
+ end
18
+ else
19
+ error_404
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def requested_page(env)
26
+ @config.pages.find { |page| page.url == env['PATH_INFO'] }
27
+ end
28
+
29
+ def render_page(page)
30
+ [200, { 'Content-Type' => 'text/html' }, [page.content]]
31
+ end
32
+
33
+ def error_404
34
+ [404, { 'Content-Type' => 'text/plain' }, ['Not Found']]
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,57 @@
1
+ require 'tilt'
2
+ require 'fronton/assets_helpers'
3
+
4
+ module Fronton
5
+ class Page
6
+ attr_reader :name, :url, :config
7
+
8
+ def initialize(name, url, options = {})
9
+ @name = name
10
+ @config = options.fetch(:config)
11
+ @digest = options.fetch(:digest, false)
12
+ @url = url
13
+ end
14
+
15
+ def content
16
+ Tilt.new(template_path, template_options).render(AssetsHelpers.new(helpers_options))
17
+ end
18
+
19
+ def save
20
+ with_digest do
21
+ File.open(save_path, 'w') { |f| f.write(content) }
22
+ end
23
+ end
24
+
25
+ def exist?
26
+ !template_path.nil?
27
+ end
28
+
29
+ private
30
+
31
+ def template_path
32
+ found_path = config.pages_paths.find do |path|
33
+ File.exist?(path.join(name))
34
+ end
35
+
36
+ found_path = found_path.join(name) if found_path
37
+
38
+ found_path
39
+ end
40
+
41
+ def template_options
42
+ { disable_escape: true, pretty: true }
43
+ end
44
+
45
+ def helpers_options
46
+ { digest: @digest, manifest: @config.manifest }
47
+ end
48
+
49
+ def save_path
50
+ config.output.join("#{File.basename(name, '.*')}.html")
51
+ end
52
+
53
+ def with_digest
54
+ @digest = true; yield; @digest = false # rubocop:disable Style/Semicolon
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,18 @@
1
+ module Fronton
2
+ module VERSION
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ TINY = 0
6
+ PRE = 'alpha'.freeze
7
+
8
+ STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
+ end
10
+
11
+ def self.version
12
+ VERSION::STRING
13
+ end
14
+
15
+ def self.gem_version
16
+ Gem::Version.new VERSION::STRING
17
+ end
18
+ end
data/lib/fronton.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'fronton/version'
2
+ require 'fronton/cli'
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,20 @@
1
+ assets:
2
+ - application.js
3
+ - application.css
4
+ assets_paths:
5
+ - assets/javascripts
6
+ - assets/stylesheets
7
+ - assets/fonts
8
+ - assets/images
9
+ - vendor/javascripts
10
+ - vendor/stylesheets
11
+ - vendor/fonts
12
+ - vendor/images
13
+ dependencies:
14
+ - rails-assets-jquery: 3.1.0
15
+ - slim: 3.0.7
16
+ output: public
17
+ pages:
18
+ - index.slim: /
19
+ pages_paths:
20
+ - pages
@@ -0,0 +1,3 @@
1
+ es:
2
+ index:
3
+ title: "Index"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
metadata ADDED
@@ -0,0 +1,124 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fronton
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Javier Aranda
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-09-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.19'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 0.19.1
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '0.19'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 0.19.1
33
+ - !ruby/object:Gem::Dependency
34
+ name: rack
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.0.1
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.0.1
53
+ - !ruby/object:Gem::Dependency
54
+ name: sprockets
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '3.7'
60
+ type: :runtime
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '3.7'
67
+ description: ''
68
+ email: javier.aranda.varo@gmail.com
69
+ executables:
70
+ - fronton
71
+ extensions: []
72
+ extra_rdoc_files:
73
+ - README.md
74
+ - LICENSE
75
+ files:
76
+ - LICENSE
77
+ - README.md
78
+ - bin/fronton
79
+ - fronton.gemspec
80
+ - lib/fronton.rb
81
+ - lib/fronton/assets_helpers.rb
82
+ - lib/fronton/cli.rb
83
+ - lib/fronton/config.rb
84
+ - lib/fronton/dependency.rb
85
+ - lib/fronton/html_server.rb
86
+ - lib/fronton/page.rb
87
+ - lib/fronton/version.rb
88
+ - template/assets/fonts/.keep
89
+ - template/assets/images/.keep
90
+ - template/assets/javascripts/.keep
91
+ - template/assets/stylesheets/.keep
92
+ - template/fronton.yml
93
+ - template/locales/es/index.yml
94
+ - template/pages/partials/.keep
95
+ - template/public/.keep
96
+ - template/vendor/fonts/.keep
97
+ - template/vendor/images/.keep
98
+ - template/vendor/javascripts/.keep
99
+ - template/vendor/stylesheets/.keep
100
+ homepage: https://github.com/javierav/fronton
101
+ licenses:
102
+ - MIT
103
+ metadata: {}
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '2.3'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">"
116
+ - !ruby/object:Gem::Version
117
+ version: 1.3.1
118
+ requirements: []
119
+ rubyforge_project:
120
+ rubygems_version: 2.6.6
121
+ signing_key:
122
+ specification_version: 4
123
+ summary: A command-line tool for build frontend apps in Ruby
124
+ test_files: []