class Palimpsest::Environment
An environment is populated with the contents of a site’s repository at a specified commit. Alternatively, a single directory can be used to populate the environment. The environment’s files are rooted in a temporary {#directory}. An environment is the primary way to interact with a site’s files.
An environment loads a {#config} file from the working {#directory}; by default, ‘palimpsest_config.yml`.
Paths are all relative to the working {#directory}.
““yml # example of palimpsest_config.yml
# component settings :components:
# all component paths are relative to the base :base: _components # list of components :paths: #- [ components_path, install_path ] - [ my_app/templates, apps/my_app/templates ] - [ my_app/extra, apps/my_app ]
# externals settings :externals:
# server or local path that repos are under :server: "https://github.com/razor-x" # list of external repos :repos: #- [ name, install_path, branch, server (optional) ] - [ my_app, apps/my_app, master ] - [ sub_app, apps/my_app/sub_app, my_feature, "https://bitbucket.org/razorx" ]
# list of excludes # matching paths are removed with {#remove_excludes}. :excludes:
- _assets - apps/*/.gitignore
# asset settings :assets:
# all options are passed to Assets#options # options will use defaults set in Palimpsest::Asset::DEFAULT_OPTIONS if unset here # unless otherwise mentioned, options can be set or overridden per asset type :options: # opening and closing brackets for asset source tags # global option only: cannot be overridden per asset type :src_pre: "[%" :src_post: "%]" # relative directory to save compiled assets :output: compiled # assume assets will be served under here :cdn: https://cdn.example.com/ # compiled asset names include a uniqe hash by default # this can be toggled off :hash: false # directories to scan for files with asset tags :sources: # putting assets/stylesheets first would allow asset tags, # e.g. for images, to be used in your stylesheets - assets/stylesheets - public - app/src # all other keys are asset types :javascripts: :options: :js_compressor: :uglifier # these paths are loaded into the sprockets environment :paths: - assets/javascripts - other/javascripts # this is another asset type which will have it's own namespace :stylesheets: :options: :css_compressor: :sass :paths: - assets/stylesheets # images can be part of the asset pipeline :images: :options: # requires the sprockets-image_compressor gem :image_compression: true # options can be overridden per type :output: images :paths: - assets/images
““
Constants
- DEFAULT_OPTIONS
Default {#options}.
Attributes
@!attribute site
@return site to build the environment with
@!attribute treeish
@return [String] the reference used to pick the commit to build the environment with
@!attribute [r] populated
@return [Boolean] true if the site's repo has been extracted
@!attribute site
@return site to build the environment with
@!attribute treeish
@return [String] the reference used to pick the commit to build the environment with
@!attribute [r] populated
@return [Boolean] true if the site's repo has been extracted
@!attribute site
@return site to build the environment with
@!attribute treeish
@return [String] the reference used to pick the commit to build the environment with
@!attribute [r] populated
@return [Boolean] true if the site's repo has been extracted
Public Class Methods
# File lib/palimpsest/environment.rb, line 124 def initialize site: nil, treeish: 'master', options: {} @populated = false self.options options self.site = site if site self.treeish = treeish end
Public Instance Methods
@return [Array<Assets>] assets with settings and paths loaded from config
# File lib/palimpsest/environment.rb, line 277 def assets return @assets if @assets @assets = [] config[:assets].each do |type, opt| next if [:sources].include? type next if opt[:paths].nil? assets = Assets.new directory: directory, paths: opt[:paths] assets.options config[:assets][:options] unless config[:assets][:options].nil? assets.options opt[:options] unless opt[:options].nil? assets.type = type @assets << assets end unless config[:assets].nil? @assets end
Removes the environment’s working directory. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 173 def cleanup FileUtils.remove_entry_secure directory if @directory @config = nil @directory = nil @assets = [] @components = [] @populated = false self end
Finds all assets in {#sources_with_assets} and generates the assets and updates the sources. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 318 def compile_assets sources_with_assets.each do |file| source = File.read file assets.each { |a| a.update_source! source } Utility.write source, file, preserve: true end self end
@return [Array<Component>] components with paths loaded from config
# File lib/palimpsest/environment.rb, line 221 def components return @components if @components return [] if config[:components].nil? return [] if config[:components][:paths].nil? @components = [] base = directory base += config[:components][:base].nil? ? '' : '/' + config[:components][:base] config[:components][:paths].each do |paths| @components << Component.new(source_path: "#{base}/#{paths[0]}", install_path: "#{directory}/#{paths[1]}") end @components end
@param settings [Hash] merged with current config @return [Hash] configuration loaded from {#options}‘[:config_file]` under {#directory}
# File lib/palimpsest/environment.rb, line 210 def config settings = {} if @config.nil? populate unless populated @config = YAML.load_file "#{directory}/#{options[:config_file]}" validate_config if @config end @config.merge! settings end
Copy the contents of the working directory. @param dest [String] path to copy environment’s files to @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 165 def copy dest: site.path FileUtils.mkdir_p dest FileUtils.cp_r Dir["#{directory}/*"], dest, preserve: true self end
@return [String] the environment’s working directory
# File lib/palimpsest/environment.rb, line 153 def directory if @directory.nil? name = site.nil? ? '' : site.name @directory = Utility.make_random_directory options[:tmp_dir], "#{options[:dir_prefix]}#{name}_" else @directory end end
@return [Array<External>] externals loaded from config
# File lib/palimpsest/environment.rb, line 246 def externals return @externals if @externals return [] if config[:externals].nil? return [] if config[:externals][:repos].nil? @externals = [] config[:externals][:repos].each do |repo| source = repo[3].nil? ? config[:externals][:server] : repo[3] @externals << External.new(name: repo[0], source: source, branch: repo[2], install_path: "#{directory}/#{repo[1]}" ) end @externals end
Install all components. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 240 def install_components components.each { |c| c.install } self end
Install all externals. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 263 def install_externals externals.each { |e| e.install.cleanup } self end
Uses {DEFAULT_OPTIONS} as initial value. @param options [Hash] merged with current options @return [Hash] current options
# File lib/palimpsest/environment.rb, line 134 def options options={} @options ||= DEFAULT_OPTIONS @options = @options.merge options end
Extracts the site’s files from repository to the working directory. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 185 def populate from: :auto cleanup if populated fail RuntimeError, "Cannot populate without 'site'" if site.nil? case from when :auto if site.respond_to?(:repo) ? site.repo : nil populate from: :repo else populate from: :source end when :repo fail RuntimeError, "Cannot populate without 'treeish'" if treeish.empty? Utility.extract_repo site.repo, treeish, directory @populated = true when :source Kernel.system 'rsync', '-rt', %q{--exclude='.git/'}, "#{site.source}/", directory @populated = true end self end
Remove all excludes defined by ‘config`. @return [Environment] the current environment instance
# File lib/palimpsest/environment.rb, line 270 def remove_excludes return self if config[:excludes].nil? config[:excludes].map{ |e| Dir["#{directory}/#{e}"] }.flatten.each { |e| FileUtils.remove_entry_secure e } self end
@see Environment#site
# File lib/palimpsest/environment.rb, line 140 def site= site fail RuntimeError, "Cannot redefine 'site' once populated" if populated @site = site end
@return [Array] all source files with asset tags
# File lib/palimpsest/environment.rb, line 297 def sources_with_assets return [] if config[:assets].nil? return [] if config[:assets][:sources].nil? @sources_with_assets = [] opts = {} [:src_pre, :src_post].each do |opt| opts[opt] = config[:assets][:options][opt] unless config[:assets][:options][opt].nil? end unless config[:assets][:options].nil? config[:assets][:sources].each do |path| @sources_with_assets << Assets.find_tags("#{directory}/#{path}", nil, opts) end @sources_with_assets.flatten end
@see Environment#treeish
# File lib/palimpsest/environment.rb, line 146 def treeish= treeish fail RuntimeError, "Cannot redefine 'treeish' once populated" if populated fail TypeError unless treeish.is_a? String @treeish = treeish end
Private Instance Methods
Checks the option in the asset key.
# File lib/palimpsest/environment.rb, line 336 def validate_asset_options opts opts.each do |k,v| fail RuntimeError, 'bad option in config' if k == :sprockets_options fail RuntimeError, message if k == :output && ! Utility.safe_path?(v) end end
Checks the config file for invalid settings. @todo refactor this
-
Checks that paths are not absolute or use ‘../` or `~/`.
# File lib/palimpsest/environment.rb, line 332 def validate_config message = 'bad path in config' # Checks the option in the asset key. def validate_asset_options opts opts.each do |k,v| fail RuntimeError, 'bad option in config' if k == :sprockets_options fail RuntimeError, message if k == :output && ! Utility.safe_path?(v) end end @config[:excludes].each do |v| fail RuntimeError, message unless Utility.safe_path? v end unless @config[:excludes].nil? @config[:external].each do |k, v| next if k == :server v.each do |repo| fail RuntimeError, message unless Utility.safe_path? repo[1] end unless v.nil? end unless @config[:external].nil? @config[:components].each do |k,v| # process @config[:components][:base] then go to the next option if k == :base fail RuntimeError, message unless Utility.safe_path? v next end unless v.nil? # process @config[:components][:paths] if k == :paths v.each do |path| fail RuntimeError, message unless Utility.safe_path? path[0] fail RuntimeError, message unless Utility.safe_path? path[1] end end end unless @config[:components].nil? @config[:assets].each do |k, v| # process @config[:assets][:options] then go to the next option if k == :options validate_asset_options v next end unless v.nil? # process @config[:assets][:sources] then go to the next option if k == :sources v.each_with_index do |source, i| fail RuntimeError, message unless Utility.safe_path? source end next end # process each asset type in @config[:assets] v.each do |asset_key, asset_value| # process :options if asset_key == :options validate_asset_options asset_value next end unless asset_value.nil? # process each asset path asset_value.each_with_index do |path, i| fail RuntimeError, message unless Utility.safe_path? path end if asset_key == :paths end end unless @config[:assets].nil? @config end