lib/trailblazer/loader.rb in trailblazer-loader-0.0.3 vs lib/trailblazer/loader.rb in trailblazer-loader-0.0.4
- old
+ new
@@ -1,44 +1,65 @@
require "trailblazer/loader/version"
require "representable/pipeline"
+require "pp"
module Trailblazer
class Loader
# Please note that this is subject to change - we're still finding out the best way
# to explicitly load files.
#
# NOTE: i will most probably use call_sheet and dry-container here soon.
def call(options={}, &block)
options[:concepts_root] ||= "app/concepts/"
+ options[:concept_dirs] = concept_dirs
pipeline = options[:pipeline] || Representable::Pipeline[
+ FindDirectories,
FindConcepts,
- SortConcepts,
- Representable::Collect[ConceptName, ConceptFiles] # per concept.
+ # PrintConcepts,
+ SortByLevel,
+ Representable::Collect[ConceptName, ConceptFiles, SortCreateFirst, SortOperationLast, AddConceptFiles] # per concept.
]
if args = options[:insert] # FIXME: this only implements a sub-set.
# pipeline = Representable::Pipeline::Insert.(pipeline, *args) # FIXME: implement :before in Pipeline.
- pipeline[2].insert(pipeline[2].index(args.last[:before]), args.first)
+ pipeline[3].insert(pipeline[3].index(args.last[:before]), args.first)
end
files = pipeline.([], options).flatten
- # require "pp"
- # pp files
+ pp files
load_files(files, &block)
end
- FindConcepts = ->(input, options) { Dir.glob("#{options[:concepts_root]}**/") }
- # lame heuristic, but works for me: sort by nested levels.
+ def concept_dirs
+ %w{ callback cell contract operation policy representer view }
+ end
+
+ FindDirectories = ->(input, options) { Dir.glob("#{options[:concepts_root]}**/") }
+ # Filter out all directories containing /(callback|cell|contract|operation|policy|representer|view)/
+ FindConcepts = ->(input, options) { input.shift; input.reject { |dir| dir =~ /(#{options[:concept_dirs].join("|")})/ } }
+ PrintConcepts = ->(input, options) { puts " concepts: #{input.inspect}"; input }
+
+ # lame heuristic, but works for me: sort by directory levels.
# app/concepts/comment
# app/concepts/api/v1/comment
- SortConcepts = ->(input, options) { input.sort { |a, b| a.split("/").size <=> b.split("/").size } }
+ SortByLevel = ->(input, options) { input.sort { |a, b| a.split("/").size <=> b.split("/").size } }
# Extract concept name from path, e.g. /api/v1/comment.
ConceptName = ->(input, options) { options[:name] = input.sub(options[:concepts_root], "").chomp("/"); [] }
# Find all .rb files in one particular concept directory, e.g. as in /concepts/comment/*.rb.
- ConceptFiles = ->(input, options) { input += Dir.glob("#{options[:concepts_root]}#{options[:name]}/*.rb") }
+ ConceptFiles = ->(input, options) do
+ Dir.glob("#{options[:concepts_root]}#{options[:name]}/*.rb") + # .rb files directly in this concept.
+ Dir.glob("#{options[:concepts_root]}#{options[:name]}/*/*.rb"). # .rb in :concept/operation/*.rb
+ find_all { |file| file =~ /(#{options[:concept_dirs].join("|")})/ } # but only those, no sub-concepts!
+ end
+
+ # operation files should be loaded after callbacks, policies, and the like: [callback.rb, contract.rb, policy.rb, operation.rb]
+ SortOperationLast = ->(input, options) { input.sort { |a, b| (a =~ /operation/ && b !~ /operation/) ? 1 : -1 } }
+ SortCreateFirst = ->(input, options) { input.sort }
+ AddConceptFiles = ->(input, options) { input }
+
private
def load_files(files)
files.each { |file| yield file }