forked from instructure/canvas-lms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
brandable_css.rb
96 lines (80 loc) · 3.61 KB
/
brandable_css.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
module BrandableCSS
require 'rails'
CONFIG = YAML.load_file(Rails.root.join('config/brandable_css.yml')).freeze
BRANDABLE_VARIABLES = JSON.parse(File.read(Rails.root.join(CONFIG['paths']['brandable_variables_json']))).freeze
SASS_STYLE = ENV['SASS_STYLE'] || (Rails.env.production? ? 'compressed' : 'nested')
class << self
def variables_map
@variables_map ||= BRANDABLE_VARIABLES.each_with_object({}) do |variable_group, memo|
variable_group['variables'].each { |variable| memo[variable['variable_name']] = variable }
end.freeze
end
# gets the *effective* value for a brandable variable
def brand_variable_value(variable_name, active_brand_config=nil)
explicit_value = active_brand_config && active_brand_config.get_value(variable_name).presence
return explicit_value if explicit_value
config = variables_map[variable_name]
default = config['default']
return brand_variable_value(default[1..-1], active_brand_config) if default && default.starts_with?('$')
# while in our sass, we want `url(/images/foo.png)`,
# the Rails Asset Helpers expect us to not have the '/images/', eg: <%= image_tag('foo.png') %>
default.sub!(/^\/images\//, '') if config['type'] == 'image'
default
end
def variants
@variants ||= CONFIG['variants'].map{|(k)| k }.freeze
end
def brandable_variants
@brandable_variants ||= CONFIG['variants'].select{|_, v| v['brandable']}.map{ |k,_| k }.freeze
end
def combined_checksums
return @combined_checksums if ActionController::Base.perform_caching && defined? @combined_checksums
file = Rails.root.join(CONFIG['paths']['bundles_with_deps'] + SASS_STYLE)
if file.exist?
@combined_checksums = JSON.parse(file.read).each_with_object({}) do |(k, v), memo|
memo[k] = v['combinedChecksum']
end.freeze
elsif Rails.env.production?
raise "you need to run #{cli} before you can serve css."
else
# for dev/test there might be cases where you don't want it to raise an exception
# if you haven't ran `brandable_css` and the manifest file doesn't exist yet.
# eg: you want to test a controller action and you don't care that it links
# to a css file that hasn't been created yet.
default_value = "Error: unknown css checksum. you need to run #{cli}"
@combined_checksums = Hash.new(default_value).freeze
end
end
# bundle path should be something like "bundles/speedgrader" or "plugins/analytics/something"
def fingerprint_for(bundle_path, variant)
key = ["#{bundle_path}.scss", variant].join(CONFIG['manifest_key_seperator'])
fingerprint = combined_checksums[key]
raise "Fingerprint not found. #{bundle_path} #{variant}" unless fingerprint
fingerprint
end
def all_fingerprints_for(bundle_path)
variants.each_with_object({}) do |variant, object|
object[variant] = fingerprint_for(bundle_path, variant)
end
end
def cli
'./node_modules/.bin/brandable_css'
end
def compile_all!
run_cli!
end
def compile_brand!(brand_id)
run_cli!('--brand-id', brand_id)
end
private
def run_cli!(*args)
# this makes sure the symlinks to app/stylesheets/plugins/analytics, etc exist
# so their scss files can be picked up and compiled with everything else
require 'config/initializers/plugin_symlinks'
command = [cli].push(*args).shelljoin + ' 2>&1'
msg = "running BrandableCSS CLI: #{command}"
Rails.logger.try(:debug, msg)
raise "Error: #{msg}" unless system(command)
end
end
end