Class: Slinky::ManifestFile
- Inherits:
-
Object
- Object
- Slinky::ManifestFile
- Defined in:
- lib/slinky/manifest.rb
Instance Attribute Summary collapse
-
#build_path ⇒ Object
Returns the value of attribute build_path.
-
#directives ⇒ Object
readonly
Returns the value of attribute directives.
-
#last_built ⇒ Object
readonly
Returns the value of attribute last_built.
-
#manifest ⇒ Object
readonly
Returns the value of attribute manifest.
-
#parent ⇒ Object
readonly
Returns the value of attribute parent.
-
#source ⇒ Object
Returns the value of attribute source.
-
#updated ⇒ Object
readonly
Returns the value of attribute updated.
Instance Method Summary collapse
-
#build ⇒ Object
Builds the file by handling and compiling it and then copying it to the build path.
-
#build_to ⇒ Object
Path to which the file will be built.
-
#compile(path, to = nil) ⇒ Object
Takes a path and compiles the file if necessary.
-
#dependencies ⇒ Object
Gets the list of manifest files that this one depends on according to its directive list and the dependencies config option.
-
#external_dependencies ⇒ Object
The list of paths to files external to the manifest that this file depends on.
- #external_dependencies_updated? ⇒ Boolean
-
#find_directives ⇒ Symbol => [String]
Looks through the file for directives.
-
#handle_directives(path, to = nil) ⇒ Object
If there are any build directives for this file, the file is read and the directives are handled appropriately and a new file is written to a temp location.
-
#in_tree?(path) ⇒ Boolean
Predicate which determines whether the file is the supplied path or lies on supplied tree.
-
#initialize(source, build_path, manifest, parent = nil, options = {:devel => false}) ⇒ ManifestFile
constructor
A new instance of ManifestFile.
- #inspect ⇒ Object
- #invalidate ⇒ Object
-
#matches?(s, match_glob = false) ⇒ Boolean
Predicate which determines whether the supplied name is the same as the file’s name, taking into account compiled file extensions.
-
#matches_path?(s, match_glob = false) ⇒ Boolean
Predicate which determines whether the file matches (see ‘ManifestFile#matches?`) the full path relative to the manifest root.
-
#md5 ⇒ Object
Gets the md5 hash of the source file.
-
#output_path ⇒ Object
Returns the path to which this file should be output.
-
#process(to = nil, should_compile = true) ⇒ Object
Gets manifest file ready for serving or building by handling the directives and compiling the file if neccesary.
-
#relative_output_path ⇒ Object
Returns the output path relative to the manifest directory.
-
#relative_source_path ⇒ Object
returns the source path relative to the manifest directory.
- #should_build ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(source, build_path, manifest, parent = nil, options = {:devel => false}) ⇒ ManifestFile
Returns a new instance of ManifestFile.
503 504 505 506 507 508 509 510 511 512 513 514 |
# File 'lib/slinky/manifest.rb', line 503 def initialize source, build_path, manifest, parent = nil, = {:devel => false} @parent = parent @source = Pathname.new(source).cleanpath.to_s @last_built = Time.at(0) @cfile = Compilers.cfile_for_file(@source) @directives = find_directives @build_path = build_path @manifest = manifest @devel = true if [:devel] end |
Instance Attribute Details
#build_path ⇒ Object
Returns the value of attribute build_path.
500 501 502 |
# File 'lib/slinky/manifest.rb', line 500 def build_path @build_path end |
#directives ⇒ Object (readonly)
Returns the value of attribute directives.
501 502 503 |
# File 'lib/slinky/manifest.rb', line 501 def directives @directives end |
#last_built ⇒ Object (readonly)
Returns the value of attribute last_built.
501 502 503 |
# File 'lib/slinky/manifest.rb', line 501 def last_built @last_built end |
#manifest ⇒ Object (readonly)
Returns the value of attribute manifest.
501 502 503 |
# File 'lib/slinky/manifest.rb', line 501 def manifest @manifest end |
#parent ⇒ Object (readonly)
Returns the value of attribute parent.
501 502 503 |
# File 'lib/slinky/manifest.rb', line 501 def parent @parent end |
#source ⇒ Object
Returns the value of attribute source.
500 501 502 |
# File 'lib/slinky/manifest.rb', line 500 def source @source end |
#updated ⇒ Object (readonly)
Returns the value of attribute updated.
501 502 503 |
# File 'lib/slinky/manifest.rb', line 501 def updated @updated end |
Instance Method Details
#build ⇒ Object
Builds the file by handling and compiling it and then copying it to the build path
756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 |
# File 'lib/slinky/manifest.rb', line 756 def build return nil unless should_build if !File.exists? @build_path FileUtils.mkdir_p(@build_path) end to = build_to path = process to if path != to FileUtils.cp(path.to_s, to.to_s) @last_built = Time.now end to end |
#build_to ⇒ Object
Path to which the file will be built
750 751 752 |
# File 'lib/slinky/manifest.rb', line 750 def build_to Pathname.new(@build_path) + output_path.basename end |
#compile(path, to = nil) ⇒ Object
Takes a path and compiles the file if necessary.
669 670 671 672 673 674 675 676 677 678 679 680 |
# File 'lib/slinky/manifest.rb', line 669 def compile path, to = nil if @cfile cfile = @cfile.clone cfile.source = path cfile.print_name = @source cfile.output_path = to if to cfile.file do |cpath, _, _, _| path = cpath end end path ? Pathname.new(path) : nil end |
#dependencies ⇒ Object
Gets the list of manifest files that this one depends on according to its directive list and the dependencies config option.
Throws a FileNotFoundError if a dependency doesn’t exist in the tree.
527 528 529 530 531 532 533 534 535 536 537 538 539 |
# File 'lib/slinky/manifest.rb', line 527 def dependencies SlinkyError.batch_errors do (@directives[:slinky_require].to_a + @manifest.config.dependencies["/" + relative_source_path.to_s].to_a).map{|rf| required = parent.find_by_path(rf, true).flatten if required.empty? error = "Could not find file #{rf} required by /#{relative_source_path}" SlinkyError.raise FileNotFoundError, error end required }.flatten end end |
#external_dependencies ⇒ Object
The list of paths to files external to the manifest that this file depends on
689 690 691 692 693 |
# File 'lib/slinky/manifest.rb', line 689 def external_dependencies (@directives[:slinky_depends_external] || []).map{|ed| Dir.glob(File.join(@manifest.dir, ed)) }.flatten end |
#external_dependencies_updated? ⇒ Boolean
695 696 697 698 699 |
# File 'lib/slinky/manifest.rb', line 695 def external_dependencies_updated? return false if external_dependencies.empty? external_dependencies.map{|x| File.mtime(x)}.max > (@updated || Time.at(0)) end |
#find_directives ⇒ Symbol => [String]
Looks through the file for directives
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 |
# File 'lib/slinky/manifest.rb', line 618 def find_directives _, _, ext = @source.match(EXTENSION_REGEX).to_a directives = {} # check if this file might include directives if @cfile || DIRECTIVE_FILES.include?(ext) # make sure the file isn't too big to scan stat = File::Stat.new(@source) if stat.size < 1024*1024 File.open(@source) {|f| matches = f.read.scan(BUILD_DIRECTIVES).to_a matches.each{|slice| key, value = slice.compact directives[key.to_sym] ||= [] directives[key.to_sym] << value[1..-2] if value } } rescue nil end end @directives = directives end |
#handle_directives(path, to = nil) ⇒ Object
If there are any build directives for this file, the file is read and the directives are handled appropriately and a new file is written to a temp location.
645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 |
# File 'lib/slinky/manifest.rb', line 645 def handle_directives path, to = nil if path && @directives.size > 0 out = File.read(path) out.gsub!(DEPENDS_DIRECTIVE, "") out.gsub!(EXTERNAL_DEPENDS_DIRECTIVE, "") out.gsub!(REQUIRE_DIRECTIVE, "") out.gsub!(SCRIPTS_DIRECTIVE){ @manifest.scripts_string } out.gsub!(STYLES_DIRECTIVE){ @manifest.styles_string } out.gsub!(PRODUCT_DIRECTIVE){ @manifest.product_string($2[1..-2]) } to = to || Tempfile.new("slinky").path + ".cache" File.open(to, "w+"){|f| f.write(out) } to else path end end |
#in_tree?(path) ⇒ Boolean
Predicate which determines whether the file is the supplied path or lies on supplied tree
585 586 587 588 589 590 |
# File 'lib/slinky/manifest.rb', line 585 def in_tree? path full_path = @manifest.dir + "/" + path abs_path = Pathname.new(full_path)..to_s dir = Pathname.new(@source).dirname..to_s dir.start_with?(abs_path) || abs_path == @source end |
#inspect ⇒ Object
776 777 778 |
# File 'lib/slinky/manifest.rb', line 776 def inspect to_s end |
#invalidate ⇒ Object
516 517 518 519 |
# File 'lib/slinky/manifest.rb', line 516 def invalidate @last_built = Time.at(0) @last_md5 = nil end |
#matches?(s, match_glob = false) ⇒ Boolean
Predicate which determines whether the supplied name is the same as the file’s name, taking into account compiled file extensions. For example, if mf refers to “/tmp/test/hello.sass”, ‘mf.matches? “hello.sass”` and `mf.matches? “hello.css”` should both return true.
550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 |
# File 'lib/slinky/manifest.rb', line 550 def matches? s, match_glob = false name = Pathname.new(@source).basename.to_s output = output_path.basename.to_s # check for stars that are not escaped a = [""] last = "" s.each_char {|c| if c != "*" || last == "\\" a[-1] << c else a << "" end last = c } if match_glob && a.size > 1 r2 = a.reduce{|a, x| /#{a}.*#{x}/} name.match(r2) || output.match(r2) else name == s || output == s end end |
#matches_path?(s, match_glob = false) ⇒ Boolean
Predicate which determines whether the file matches (see ‘ManifestFile#matches?`) the full path relative to the manifest root.
576 577 578 579 580 581 |
# File 'lib/slinky/manifest.rb', line 576 def matches_path? s, match_glob = false p = Pathname.new(s) dir = Pathname.new("/" + relative_source_path.to_s).dirname matches?(p.basename.to_s, match_glob) && dir == p.dirname end |
#md5 ⇒ Object
Gets the md5 hash of the source file
683 684 685 |
# File 'lib/slinky/manifest.rb', line 683 def md5 Digest::MD5.hexdigest(File.read(@source)) rescue nil end |
#output_path ⇒ Object
Returns the path to which this file should be output. This is equal to the source path unless the file needs to be compiled, in which case the extension returned is the output extension
597 598 599 600 601 602 603 604 |
# File 'lib/slinky/manifest.rb', line 597 def output_path if @cfile ext = /\.[^.]*$/ Pathname.new(@source.gsub(ext, ".#{@cfile.output_ext}")) else Pathname.new(@source) end end |
#process(to = nil, should_compile = true) ⇒ Object
Gets manifest file ready for serving or building by handling the directives and compiling the file if neccesary.
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 |
# File 'lib/slinky/manifest.rb', line 706 def process to = nil, should_compile = true return if @processing # prevent infinite recursion start_time = Time.now hash = md5 if hash != @last_md5 find_directives end SlinkyError.batch_errors do depends = @directives[:slinky_depends].map{|f| ps = if f.start_with?("/") @manifest.find_by_pattern(f) else parent.find_by_path(f, true) end unless ps.size > 0 SlinkyError.raise DependencyError, "File #{f} depended on by #{@source} not found" end ps }.flatten.compact if @directives[:slinky_depends] depends ||= [] @processing = true # process each file on which we're dependent, watching out for # infinite loops depends.each{|f| f.process } @processing = false # get hash of source file if @last_path && hash == @last_md5 && depends.all?{|f| f.updated < start_time} && !external_dependencies_updated? @last_path else @last_md5 = hash @updated = Time.now # mangle file appropriately f = should_compile ? (compile @source) : @source @last_path = handle_directives(f, to) end end end |
#relative_output_path ⇒ Object
Returns the output path relative to the manifest directory
612 613 614 |
# File 'lib/slinky/manifest.rb', line 612 def relative_output_path output_path.relative_path_from(Pathname.new(@manifest.dir)) end |
#relative_source_path ⇒ Object
returns the source path relative to the manifest directory
607 608 609 |
# File 'lib/slinky/manifest.rb', line 607 def relative_source_path Pathname.new(@source).relative_path_from(Pathname.new(@manifest.dir)) end |
#should_build ⇒ Object
772 773 774 |
# File 'lib/slinky/manifest.rb', line 772 def should_build @manifest.files_for_all_products.include?(self) || ![".js", ".css"].include?(output_path.extname) end |
#to_s ⇒ Object
780 781 782 |
# File 'lib/slinky/manifest.rb', line 780 def to_s "<Slinky::ManifestFile '#{@source}'>" end |