maglove 0.8.1 → 1.0.2

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 (73) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +157 -0
  4. data/Gemfile.lock +59 -49
  5. data/bin/maglove +13 -13
  6. data/data/maglove/export.haml +11 -0
  7. data/data/maglove/index.haml +17 -0
  8. data/data/maglove/maglove.css +62 -0
  9. data/data/maglove/maglove.haml +18 -0
  10. data/data/maglove/maglove.js +68 -0
  11. data/lib/block_resolver.rb +6 -0
  12. data/lib/ext/thor/option.rb +43 -0
  13. data/lib/magloft/api.rb +39 -0
  14. data/lib/magloft/api_caller.rb +67 -0
  15. data/lib/magloft/remote_collection.rb +50 -0
  16. data/lib/magloft/remote_resource.rb +124 -0
  17. data/lib/magloft/transformable.rb +11 -0
  18. data/lib/magloft/typeloft_block.rb +18 -0
  19. data/lib/magloft/typeloft_image.rb +18 -0
  20. data/lib/magloft/typeloft_template.rb +18 -0
  21. data/lib/magloft/typeloft_theme.rb +41 -0
  22. data/lib/magloft.rb +3 -0
  23. data/lib/maglove/application.rb +10 -12
  24. data/lib/maglove/asset/theme.rb +37 -32
  25. data/lib/maglove/commands/assets.rb +85 -0
  26. data/lib/maglove/commands/base.rb +55 -0
  27. data/lib/maglove/commands/fonts.rb +69 -0
  28. data/lib/maglove/commands/main.rb +24 -0
  29. data/lib/maglove/commands/theme.rb +197 -0
  30. data/lib/maglove/helper/log_helper.rb +3 -18
  31. data/lib/maglove/middleware/live_reload.rb +97 -0
  32. data/lib/maglove/phantom_script.rb +9 -10
  33. data/lib/maglove/server.rb +46 -78
  34. data/lib/maglove/tilt/coffee_template.rb +7 -6
  35. data/lib/maglove/tilt/haml_template.rb +4 -4
  36. data/lib/maglove/tilt/js_template.rb +8 -8
  37. data/lib/maglove/tilt/less_template.rb +5 -4
  38. data/lib/maglove/tilt/scss_template.rb +17 -11
  39. data/lib/maglove/tilt/yaml_template.rb +3 -2
  40. data/lib/maglove/version.rb +1 -1
  41. data/lib/maglove/workspace.rb +41 -0
  42. data/lib/maglove.rb +38 -49
  43. data/lib/powersnap.rb +24 -0
  44. data/lib/workspace/workspace_dir/archive.rb +18 -0
  45. data/lib/workspace/workspace_dir.rb +98 -0
  46. data/lib/workspace/workspace_file/archive.rb +45 -0
  47. data/lib/workspace/workspace_file/media.rb +19 -0
  48. data/lib/workspace/workspace_file/net.rb +18 -0
  49. data/lib/workspace/workspace_file/parse.rb +21 -0
  50. data/lib/workspace/workspace_file.rb +99 -0
  51. data/lib/workspace.rb +11 -0
  52. data/maglove.gemspec +12 -12
  53. metadata +100 -86
  54. data/data/maglove/dump.haml +0 -58
  55. data/data/maglove/sdk.haml +0 -27
  56. data/lib/ext/commander/command.rb +0 -32
  57. data/lib/ext/commander/methods.rb +0 -8
  58. data/lib/maglove/asset/base_theme.rb +0 -17
  59. data/lib/maglove/command/compile.rb +0 -44
  60. data/lib/maglove/command/compress.rb +0 -28
  61. data/lib/maglove/command/copy.rb +0 -35
  62. data/lib/maglove/command/core.rb +0 -23
  63. data/lib/maglove/command/font.rb +0 -80
  64. data/lib/maglove/command/server.rb +0 -16
  65. data/lib/maglove/command/sync.rb +0 -17
  66. data/lib/maglove/command/theme.rb +0 -175
  67. data/lib/maglove/command/util.rb +0 -45
  68. data/lib/maglove/helper/asset_helper.rb +0 -24
  69. data/lib/maglove/helper/command_helper.rb +0 -67
  70. data/lib/maglove/helper/theme_helper.rb +0 -105
  71. data/lib/maglove/server/hpub.rb +0 -185
  72. data/lib/maglove/template/tumblr.rb +0 -81
  73. data/lib/maglove/tilt/twig_template.rb +0 -49
@@ -0,0 +1,67 @@
1
+ module MagLoft
2
+ class ApiCaller < Dialers::Caller
3
+ MAX_RETRIES = 0
4
+ TIMEOUT_IN_SECONDS = 600
5
+ MAGLOFT_API_URL = "https://www.magloft.dev"
6
+ MAGLOFT_CDN_URL = "https://cdn.magloft.dev/"
7
+
8
+ setup_api(url: MAGLOFT_API_URL) do |faraday|
9
+ faraday.request :json
10
+ faraday.request :request_headers, accept: "application/json"
11
+ faraday.response :json
12
+ faraday.adapter :net_http
13
+ faraday.options.timeout = TIMEOUT_IN_SECONDS
14
+ faraday.options.open_timeout = TIMEOUT_IN_SECONDS
15
+ faraday.ssl.verify = false
16
+ end
17
+
18
+ def http_call(request_options, current_retries = 0)
19
+ request_options.headers["X-Magloft-Accesstoken"] = Api.client.token
20
+ super
21
+ end
22
+
23
+ def transform(response)
24
+ self.class.short_circuits.search_for_stops(response)
25
+ Transformable.new(response)
26
+ end
27
+
28
+ short_circuits.add(
29
+ if: -> (response) { Dialers::Status.new(response.status).server_error? },
30
+ do: -> (response) { fail Dialers::ServerError, response }
31
+ )
32
+
33
+ short_circuits.add(
34
+ if: -> (response) { Dialers::Status.new(response.status).is?(404) },
35
+ do: -> (response) { fail Dialers::NotFoundError, response }
36
+ )
37
+
38
+ short_circuits.add(
39
+ if: -> (response) { Dialers::Status.new(response.status).is?(409) },
40
+ do: -> (response) { fail ConflictError, response }
41
+ )
42
+
43
+ short_circuits.add(
44
+ if: -> (response) { Dialers::Status.new(response.status).is?(400) },
45
+ do: -> (response) { fail ValidationError, response }
46
+ )
47
+
48
+ short_circuits.add(
49
+ if: -> (response) { Dialers::Status.new(response.status).is?(422) },
50
+ do: -> (response) { fail ValidationError, response }
51
+ )
52
+
53
+ short_circuits.add(
54
+ if: -> (response) { Dialers::Status.new(response.status).is?(401) },
55
+ do: -> (response) { fail UnauthorizedError, response }
56
+ )
57
+
58
+ class ConflictError < Dialers::ErrorWithResponse
59
+ end
60
+
61
+ class ValidationError < Dialers::ErrorWithResponse
62
+ end
63
+
64
+ class UnauthorizedError < Dialers::ErrorWithResponse
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,50 @@
1
+ module MagLoft
2
+ class RemoteCollection
3
+ def initialize(resource_class, filter = {})
4
+ @resource_class = resource_class
5
+ @filter = filter
6
+ end
7
+
8
+ def new(attributes)
9
+ @resource_class.new(attributes.merge(@filter))
10
+ end
11
+
12
+ def find(id)
13
+ @resource_class.where(@filter.merge(id: id)).first
14
+ end
15
+
16
+ def where(params)
17
+ @resource_class.where(params.merge(@filter))
18
+ end
19
+
20
+ def find_one(params)
21
+ @resource_class.find_one(params.merge(@filter))
22
+ end
23
+
24
+ def all
25
+ @resource_class.where(@filter)
26
+ end
27
+
28
+ def method_missing(name, *args, &block)
29
+ if name[0..7] == "find_by_" and args.length == 1
30
+ attribute = name[8..-1].to_sym
31
+ if @resource_class.remote_attributes.include?(attribute)
32
+ params = {}
33
+ params[attribute] = args.first
34
+ return self.find_one(params.merge(@filter))
35
+ end
36
+ end
37
+ super
38
+ end
39
+
40
+ def respond_to_missing?(method_name, include_private = false)
41
+ method_name.to_s.start_with?('find_by_') || super
42
+ end
43
+
44
+ def create(attributes = {})
45
+ entity = @resource_class.new(attributes.merge(@filter))
46
+ entity.save
47
+ entity
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,124 @@
1
+ module MagLoft
2
+ class RemoteResource
3
+ attr_accessor :changed_data, :id
4
+ attr_reader :destroyed
5
+
6
+ def initialize(attributes = {})
7
+ allowed_attributes = attributes.slice(*self.class.remote_attributes)
8
+ Dialers::AssignAttributes.call(self, allowed_attributes.without(:id))
9
+ end
10
+
11
+ def changed?
12
+ self.changed_data.keys.count > 0
13
+ end
14
+
15
+ def destroyed?
16
+ self.destroyed == true
17
+ end
18
+
19
+ def save
20
+ return false if destroyed? or !changed?
21
+ if self.changed_data.keys.count > 0
22
+ if self.id.nil?
23
+ transformable = Api.client.api_caller.post(self.class.endpoint, self.changed_data)
24
+ else
25
+ transformable = Api.client.api_caller.put("#{self.class.endpoint}/#{self.id}", self.changed_data.without(:id))
26
+ end
27
+ transformable.transform_to_existing(self)
28
+ self.clear_changed_data!
29
+ end
30
+ self
31
+ end
32
+
33
+ def destroy
34
+ return false if self.id.nil? or self.destroyed?
35
+ transformable = Api.client.api_caller.delete("#{self.class.endpoint}/#{self.id}")
36
+ transformable.transform_to_existing(self)
37
+ @destroyed = true
38
+ self.clear_changed_data!
39
+ self
40
+ end
41
+
42
+ def changed_data
43
+ @changed_data ||= {}
44
+ end
45
+
46
+ def clear_changed_data!
47
+ self.changed_data = {}
48
+ self
49
+ end
50
+
51
+ def update_data(key, value)
52
+ if self.send(key) != value
53
+ instance_variable_set("@#{key}", value)
54
+ changed_data[key] = value
55
+ end
56
+ end
57
+
58
+ class << self
59
+ def remote_attributes
60
+ @remote_attributes ||= []
61
+ end
62
+
63
+ def remote_attribute(*args)
64
+ args.each do |arg|
65
+ remote_attributes.push(arg)
66
+ self.class_eval("attr_accessor :#{arg}")
67
+ self.class_eval("def #{arg}=(val);update_data(:#{arg}, val);end")
68
+ end
69
+ end
70
+
71
+ def endpoint(path = nil)
72
+ if path.nil?
73
+ @endpoint
74
+ else
75
+ @endpoint = path
76
+ end
77
+ end
78
+
79
+ def find(id)
80
+ api.get("#{endpoint}/#{id}").transform_to_one(self)
81
+ end
82
+
83
+ def find_one(params)
84
+ where(params).first
85
+ end
86
+
87
+ def where(params)
88
+ api.get(endpoint, params).transform_to_many(self)
89
+ end
90
+
91
+ def all
92
+ api.get(endpoint).transform_to_many(self)
93
+ end
94
+
95
+ def create(attributes = {})
96
+ entity = self.new(attributes)
97
+ entity.save
98
+ entity
99
+ end
100
+
101
+ def method_missing(name, *args, &block)
102
+ if name[0..7] == "find_by_" and args.length == 1
103
+ attribute = name[8..-1].to_sym
104
+ if remote_attributes.include?(attribute)
105
+ params = {}
106
+ params[attribute] = args.first
107
+ return self.find_one(params)
108
+ end
109
+ end
110
+ super
111
+ end
112
+
113
+ def respond_to_missing?(method_name, include_private = false)
114
+ method_name.to_s.start_with?('find_by_') || super
115
+ end
116
+
117
+ private
118
+
119
+ def api
120
+ Api.client.api_caller
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,11 @@
1
+ module MagLoft
2
+ class Transformable < Dialers::Transformable
3
+ def transform_attributes_to_object(entity_class_or_decider, attributes)
4
+ super.clear_changed_data!
5
+ end
6
+
7
+ def transform_to_existing(entity)
8
+ Dialers::AssignAttributes.call(entity, raw_data)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,18 @@
1
+ module MagLoft
2
+ class TypeloftBlock < RemoteResource
3
+ endpoint "api/maglove/v1/typeloft_blocks"
4
+ remote_attribute :identifier, :name, :contents, :typeloft_theme_id, :user_id, :created_at, :updated_at
5
+ attr_accessor :thumbnail_policy
6
+
7
+ def upload_thumbnail(file_path)
8
+ return false if thumbnail_policy.nil?
9
+ conn = Faraday.new(url: thumbnail_policy["url"]) do |f|
10
+ f.ssl.verify = false
11
+ f.headers = thumbnail_policy["headers"]
12
+ f.adapter :net_http
13
+ end
14
+ response = conn.put(nil, File.read(file_path))
15
+ return (response.status == 200)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module MagLoft
2
+ class TypeloftImage < RemoteResource
3
+ endpoint "api/maglove/v1/typeloft_images"
4
+ remote_attribute :title, :user_id, :typeloft_folder_id, :typeloft_theme_id, :remote_file, :md5
5
+ attr_accessor :policy, :content_type
6
+
7
+ def upload(file_path)
8
+ return false if policy.nil?
9
+ conn = Faraday.new(url: policy["url"]) do |f|
10
+ f.ssl.verify = false
11
+ f.headers = policy["headers"]
12
+ f.adapter :net_http
13
+ end
14
+ response = conn.put(nil, File.read(file_path))
15
+ return (response.status == 200)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module MagLoft
2
+ class TypeloftTemplate < RemoteResource
3
+ endpoint "api/maglove/v1/typeloft_templates"
4
+ remote_attribute :identifier, :title, :contents, :public, :position, :typeloft_theme_id, :user_id, :created_at, :updated_at
5
+ attr_accessor :thumbnail_policy
6
+
7
+ def upload_thumbnail(file_path)
8
+ return false if thumbnail_policy.nil?
9
+ conn = Faraday.new(url: thumbnail_policy["url"]) do |f|
10
+ f.ssl.verify = false
11
+ f.headers = thumbnail_policy["headers"]
12
+ f.adapter :net_http
13
+ end
14
+ response = conn.put(nil, File.read(file_path))
15
+ return (response.status == 200)
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,41 @@
1
+ module MagLoft
2
+ class TypeloftTheme < RemoteResource
3
+ endpoint "api/maglove/v1/typeloft_themes"
4
+ remote_attribute :identifier, :name, :description, :base_version, :widgets, :fonts, :user_id, :screenshots, :active
5
+ attr_accessor :stylesheet_policy, :javascript_policy
6
+
7
+ def typeloft_templates
8
+ RemoteCollection.new(TypeloftTemplate, { typeloft_theme_id: self.id })
9
+ end
10
+
11
+ def typeloft_images
12
+ RemoteCollection.new(TypeloftImage, { typeloft_theme_id: self.id })
13
+ end
14
+
15
+ def typeloft_blocks
16
+ RemoteCollection.new(TypeloftBlock, { typeloft_theme_id: self.id })
17
+ end
18
+
19
+ def upload_javascript(file_path)
20
+ return false if javascript_policy.nil?
21
+ conn = Faraday.new(url: javascript_policy["url"]) do |f|
22
+ f.ssl.verify = false
23
+ f.headers = javascript_policy["headers"]
24
+ f.adapter :net_http
25
+ end
26
+ response = conn.put(nil, File.read(file_path))
27
+ return (response.status == 200)
28
+ end
29
+
30
+ def upload_stylesheet(file_path)
31
+ return false if stylesheet_policy.nil?
32
+ conn = Faraday.new(url: stylesheet_policy["url"]) do |f|
33
+ f.ssl.verify = false
34
+ f.headers = stylesheet_policy["headers"]
35
+ f.adapter :net_http
36
+ end
37
+ response = conn.put(nil, File.read(file_path))
38
+ return (response.status == 200)
39
+ end
40
+ end
41
+ end
data/lib/magloft.rb ADDED
@@ -0,0 +1,3 @@
1
+ require "magloft/api"
2
+ module MagLoft
3
+ end
@@ -1,7 +1,7 @@
1
1
  module MagLove
2
2
  class Application
3
3
  include Commander::Methods
4
-
4
+
5
5
  def run
6
6
  program :version, MagLove::VERSION
7
7
  program :description, 'MagLoft Themes Toolkit'
@@ -12,17 +12,16 @@ module MagLove
12
12
  logger.level = :debug
13
13
  end
14
14
  global_option '--verbosity LEVEL', 'Specify verbosity level (*info*, debug, warn, error)' do |verbosity|
15
- verbosity = "info" if !["info", "debug", "warn", "error"].include?(verbosity.to_s)
15
+ verbosity = "info" unless ["info", "debug", "warn", "error"].include?(verbosity.to_s)
16
16
  logger.level = verbosity.to_sym
17
17
  end
18
18
  widgets_path = "widgets"
19
19
  global_option '--widgets-path PATH', 'Specify path to custom widgets' do |path|
20
- error!("▸ Invalid widgets path: #{path}") if !File.directory?(path)
20
+ error!("▸ Invalid widgets path: #{path}") unless File.directory?(path)
21
21
  widgets_path = path
22
22
  end
23
- global_option '--production'
24
23
  default_command :help
25
-
24
+
26
25
  # Register Widgets
27
26
  if File.directory?(widgets_path)
28
27
  Dir["#{widgets_path}/**/*.rb"].each do |widget_path|
@@ -31,9 +30,9 @@ module MagLove
31
30
  Hamloft.register_widget(klass_name.constantize)
32
31
  end
33
32
  end
34
-
33
+
35
34
  logger.level = ENV["LOG_LEVEL"].to_sym if ENV["LOG_LEVEL"]
36
-
35
+
37
36
  MagLove::Command::Theme.new.run
38
37
  MagLove::Command::Core.new.run
39
38
  MagLove::Command::Compile.new.run
@@ -43,18 +42,17 @@ module MagLove
43
42
  MagLove::Command::Font.new.run
44
43
  MagLove::Command::Sync.new.run
45
44
  MagLove::Command::Server.new.run
46
-
45
+
47
46
  # allow colons
48
- ARGV[0] = ARGV[0].gsub(":", "-") if ARGV[0]
49
-
47
+ ARGV[0] = ARGV[0].tr(":", "-") if ARGV[0]
48
+
50
49
  # merge first two commands
51
50
  if ARGV.length > 1 and defined_commands.keys.include?("#{ARGV[0]}-#{ARGV[1]}")
52
51
  ARGV[0] = "#{ARGV[0]}-#{ARGV[1]}"
53
52
  ARGV.slice!(1)
54
53
  end
55
-
54
+
56
55
  run!
57
56
  end
58
-
59
57
  end
60
58
  end
@@ -1,42 +1,48 @@
1
+ require "tilt"
2
+ require "sass"
3
+ require "less"
4
+ require "maglove/tilt/haml_template"
5
+ require "maglove/tilt/less_template"
6
+ require "maglove/tilt/scss_template"
7
+ require "maglove/tilt/coffee_template"
8
+ require "maglove/tilt/js_template"
9
+ require "maglove/tilt/yaml_template"
10
+
1
11
  module MagLove
2
12
  module Asset
3
13
  class Theme
4
- include MagLove::Helper::AssetHelper
14
+ include Workspace
5
15
  include MagLove::Helper::LogHelper
6
- include MagLove::Helper::ThemeHelper
7
- attr_reader :mtime, :path, :theme, :valid, :locals, :contents
16
+ attr_reader :mtime, :path, :valid, :contents, :options
8
17
 
9
18
  OUTPUT_MAPPING = {
10
19
  "haml" => "html",
11
- "twig" => "html",
12
20
  "less" => "css",
13
21
  "scss" => "css",
14
22
  "coffee" => "js",
15
23
  "yml" => "json"
16
24
  }
17
25
 
18
- def initialize(path, theme, locals={})
26
+ def initialize(path, options = {})
19
27
  @path = path
20
- @theme = theme
21
- @locals = locals
28
+ @options = options
22
29
  @mtime = File.mtime(absolute_path)
23
30
  begin
24
31
  if ::Tilt[input_type]
25
32
  template = ::Tilt.new(absolute_path)
26
- locals[:base_path] = theme_base_path(nil, theme)
27
- @contents = template.render(Object.new, locals)
33
+ @contents = template.render(Object.new, @options.merge(base_path: theme_base_dir.to_s))
28
34
  else
29
35
  @contents = File.read(absolute_path)
30
36
  end
31
- rescue Exception => e
37
+ rescue StandardError => e
32
38
  error("▸ #{e.message}")
33
39
  end
34
40
  end
35
-
41
+
36
42
  def input_type
37
- File.extname(path).gsub("\.", "")
43
+ File.extname(path).delete("\.")
38
44
  end
39
-
45
+
40
46
  def output_type
41
47
  OUTPUT_MAPPING[input_type] or input_type
42
48
  end
@@ -48,41 +54,40 @@ module MagLove
48
54
  def write!
49
55
  write_to!(output_path)
50
56
  end
51
-
57
+
52
58
  def write_to!(path)
53
- return false if not valid?
59
+ return false unless valid?
54
60
  FileUtils.mkdir_p(File.dirname(path))
55
-
56
- File.open("#{path}+", 'wb') do |f|
57
- f.write @contents
58
- end
59
-
60
- # Atomic write
61
+ File.open("#{path}+", 'wb') { |f| f.write @contents }
61
62
  FileUtils.mv("#{path}+", path)
62
-
63
- # Set mtime correctly
64
63
  File.utime(mtime, mtime, path)
65
-
66
64
  true
67
65
  ensure
68
- # Ensure tmp file gets cleaned up
69
66
  FileUtils.rm("#{path}+") if File.exist?("#{path}+")
70
67
  end
71
-
68
+
72
69
  def absolute_path
73
- File.absolute_path("src/themes/#{theme}/#{path}")
70
+ if @options[:base]
71
+ File.absolute_path("src/base/#{theme_config(:base_version)}/#{path}")
72
+ else
73
+ File.absolute_path("src/themes/#{@options[:theme]}/#{path}")
74
+ end
74
75
  end
75
76
 
76
77
  def logical_path
77
- return false if not valid?
78
- "#{File.dirname(path)}/#{File.basename(path,'.*')}.#{output_type}"
78
+ return false unless valid?
79
+ dirname = File.dirname(path)
80
+ if dirname == "/"
81
+ "#{File.basename(path, '.*')}.#{output_type}"
82
+ else
83
+ "#{dirname}/#{File.basename(path, '.*')}.#{output_type}"
84
+ end
79
85
  end
80
86
 
81
87
  def output_path
82
- return false if not valid?
83
- "dist/themes/#{theme}/#{logical_path}"
88
+ return false unless valid?
89
+ "dist/themes/#{@options[:theme]}/#{logical_path}"
84
90
  end
85
-
86
91
  end
87
92
  end
88
93
  end
@@ -0,0 +1,85 @@
1
+ module MagLove
2
+ module Commands
3
+ class Assets < Base
4
+ class_option :theme, type: :string, required: true, validator: OptionValidator
5
+
6
+ desc "compile", "Compile all assets"
7
+ def compile
8
+ invoke(:clean)
9
+ invoke(:images)
10
+ invoke(:javascript)
11
+ invoke(:stylesheet)
12
+ invoke(:yaml)
13
+ invoke(:templates)
14
+ invoke(:blocks)
15
+ end
16
+
17
+ desc "clean", "Clean theme dist directory"
18
+ def clean
19
+ info("▸ Cleaning up Theme Directory")
20
+ theme_dir(root: "dist").reset!
21
+ end
22
+
23
+ desc "images", "Copy images"
24
+ def images
25
+ info("▸ Copying Images")
26
+ workspace_dir("src/base/#{theme_config(:base_version)}").files("images/**/*.{jpg,png,gif,svg}").each do |file|
27
+ debug("~> Copying #{file}")
28
+ file.asset(theme: options.theme, base: true).write!
29
+ end
30
+ theme_dir.files("images/**/*.{jpg,png,gif,svg}").each do |file|
31
+ debug("~> Copying #{file}")
32
+ file.asset.write!
33
+ end
34
+ end
35
+
36
+ desc "javascript", "Compile JavaScript"
37
+ def javascript
38
+ info("▸ Compiling JavaScript")
39
+ theme_dir.file("theme.coffee").asset.write!
40
+ end
41
+
42
+ desc "stylesheet", "Compile Stylesheet"
43
+ def stylesheet
44
+ info("▸ Compiling Stylesheet")
45
+ theme_dir.files("theme.{scss,less}").first.asset.write!
46
+ end
47
+
48
+ desc "yaml", "Compile YAML Manifest"
49
+ def yaml
50
+ info("▸ Compiling YAML Manifest")
51
+ theme_dir.file("theme.yml").asset.write!
52
+ end
53
+
54
+ desc "templates", "Compile HAML Templates"
55
+ def templates
56
+ info("▸ Compiling HAML Templates")
57
+ asset_uri = "file://#{workspace_dir('dist').absolute_path}"
58
+ theme_config(:templates).each do |template|
59
+ debug "~> processing template #{template}"
60
+ template_file = theme_dir.file("templates/#{template}.haml")
61
+ error!("~> Template '#{template}' does not exist!") if template_file.nil?
62
+ contents = template_file.asset(asset_uri: asset_uri).contents
63
+ html_contents = gem_dir.file("export.haml").read_hamloft(theme: options.theme, contents: contents, asset_uri: asset_uri)
64
+ theme_dir(root: "dist").file("templates/#{template}.html").write(html_contents)
65
+ end
66
+ end
67
+
68
+ desc "blocks", "Compile HAML Blocks"
69
+ def blocks
70
+ info("▸ Compiling HAML Blocks")
71
+ if theme_dir.dir("blocks").exists?
72
+ asset_uri = "file://#{workspace_dir('dist').absolute_path}"
73
+ theme_dir.dir("blocks").files("**/*.haml").each do |block_file|
74
+ debug "~> processing block #{block_file.basename}"
75
+ contents = block_file.asset(asset_uri: asset_uri).contents
76
+ html_contents = gem_dir.file("export.haml").read_hamloft(theme: options.theme, contents: contents, asset_uri: asset_uri)
77
+ theme_dir(root: "dist").file("blocks/#{block_file.basename}.html").write(html_contents)
78
+ end
79
+ else
80
+ debug "~> no blocks available"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,55 @@
1
+ require "maglove/helper/log_helper"
2
+ require "maglove/asset/theme"
3
+ module MagLove
4
+ module Commands
5
+ class Base < Thor
6
+ include MagLove::Helper::LogHelper
7
+ include Workspace
8
+
9
+ def initialize(args, opts, config)
10
+ namespace = self.class.name.split("::").last.underscore
11
+ command = config[:current_command].name
12
+ Logging.mdc["full_command"] = "#{namespace}:#{command}"
13
+ super
14
+ end
15
+
16
+ private
17
+
18
+ def magloft_api
19
+ @magloft_api ||= MagLoft::Api.client(options[:token])
20
+ end
21
+
22
+ def reset_invocations(*commands)
23
+ reset_command_invocations(self.class, *commands)
24
+ end
25
+
26
+ def reset_command_invocations(parent, *commands)
27
+ if commands.length.zero?
28
+ @_invocations[parent] = []
29
+ else
30
+ commands.each do |command|
31
+ @_invocations[parent].delete(command.to_s)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ module OptionValidator
38
+ def self.validate(switch, value)
39
+ case switch
40
+ when "--theme"
41
+ File.directory?("src/themes/#{value}")
42
+ else
43
+ true
44
+ end
45
+ end
46
+
47
+ def self.message(switch, value)
48
+ case switch
49
+ when "--theme"
50
+ "The theme '#{value}' does not exist!"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end