Class Ohcount::SourceFile
In: lib/ohcount/source_file.rb
Parent: Object

SourceFile represents a single source code file.

It can be a pointer to an actual file on disk, or it may strictly be an in-memory buffer.

Methods

Attributes

file_location  [RW]  The location on disk where the file contents can currently be found. This location does not need to match the original filename.
filename  [RW]  Required. The original name of the file, as it appears in the source tree.
filenames  [RW]  An array of names of other files in the source tree which may be helpful when disambiguating the language used by the target file. For instance, the presence of an Objective-C *.m file is a clue when determining the language used in a *.h header file. This array is optional, but language identification may be less accurate without it.

Public Class methods

If you pass :contents to this initializer, then SourceFile works in memory and does not need to access the file on disk.

If you do not pass the :contents, then SourceFile will first check :file_location and then :filename (in that order) to get the file contents.

[Source]

# File lib/ohcount/source_file.rb, line 29
                def initialize(filename, options = {})
                        @filename      = filename
                        @filenames     = options[:filenames] || []
                        @contents      = options[:contents]
                        @file_location = options[:file_location]
                end

Public Instance methods

[Source]

# File lib/ohcount/source_file.rb, line 56
                def basename
                        File.basename(filename)
                end

Takes two strings and returns an array containing the count of added lines and deleted lines. Example:

  calc_diff("a\nb", "a\nc")      # [1,1] -> one added, one deleted

[Source]

# File lib/ohcount/source_file.rb, line 160
                def calc_diff(a,b)
                        LCSDiff::Diff::LCS.diff(a.split("\n"),b.split("\n")).flatten.inject([0,0]) do |m, change|
                                m[0] += 1 if change.adding?
                                m[1] += 1 if change.deleting?
                                m
                        end
                end

Returns a LocDelta reflecting the lines changed in a single language when comparing this source file ("before") to a new version ("after")

[Source]

# File lib/ohcount/source_file.rb, line 137
                def calc_loc_delta(language, after)
                        lb_before = self.language_breakdown(language)
                        lb_after = after.language_breakdown(language)

                        delta = LocDelta.new(language)

                        delta.code_added, delta.code_removed = calc_diff(lb_before.code, lb_after.code)
                        delta.comments_added, delta.comments_removed = calc_diff(lb_before.comment, lb_after.comment)

                        if lb_before.blanks > lb_after.blanks
                                delta.blanks_removed = lb_before.blanks - lb_after.blanks
                        else
                                delta.blanks_added = lb_after.blanks - lb_before.blanks
                        end

                        delta
                end

[Source]

# File lib/ohcount/source_file.rb, line 36
                def contents
                        @contents ||= File.open(@file_location || @filename) do |io|
                                io.read
                        end
                end

Returns a LocDeltaList reflecting the lines changed in all languages when comparing this source file ("before") to a new version ("after")

[Source]

# File lib/ohcount/source_file.rb, line 127
                def diff(after)
                        all_languages = (self.languages + after.languages).uniq.sort

                        all_languages.inject(LocDeltaList.new) do |sum, lang|
                                sum + calc_loc_delta(lang, after)
                        end.compact
                end

Returns true iff we represent a file and not a directory

[Source]

# File lib/ohcount/source_file.rb, line 50
                def file?
                        File.exist?(@filename) && File.file?(@filename) ||
                                @file_location && File.exist?(@file_location) && File.file?(@file_location) ||
                                @contents
                end

[Source]

# File lib/ohcount/source_file.rb, line 68
                def language_breakdown(language)
                        language_breakdowns.find { |lb| lb.name == language.to_s } || LanguageBreakdown.new(language.to_s)
                end

[Source]

# File lib/ohcount/source_file.rb, line 64
                def language_breakdowns
                        @language_breakdowns ||= parse
                end

returns the list of languages included in the parsed language_breakdowns

[Source]

# File lib/ohcount/source_file.rb, line 110
                def languages
                        language_breakdowns.collect { |lb| lb.name }
                end

[Source]

# File lib/ohcount/source_file.rb, line 92
                def licenses
                        @licenses ||= begin
                                comments = ''
                                parse do |language, semantic, line|
                                        next unless semantic == :comment
                                        # Strip leading punctuation.
                                        comments << ' ' + $1 if line =~ /^[\s[:punct:]]*(.*?)$/
                                end
                                LicenseSniffer.sniff(comments)
                        end
                end

Returns a LocList reflecting the total lines of code in each language

[Source]

# File lib/ohcount/source_file.rb, line 115
                def loc_list
                        language_breakdowns.inject(LocList.new) do |sum, lb|
                                sum + Loc.new(lb.name,
                                                                                        :code => lb.code_count, 
                                                                                        :comments => lb.comment_count,
                                                                                        :blanks => lb.blanks,
                                                                                        :filecount => 1)
                        end
                end

[Source]

# File lib/ohcount/source_file.rb, line 60
                def parse(&block)
                        @language_breakdowns = polyglot ? Ohcount::parse(contents, polyglot, &block) : []
                end

A bit complicated because a nil value can either mean that we haven‘t checked, or that we have checked but received a nil result.

[Source]

# File lib/ohcount/source_file.rb, line 44
                def polyglot
                        return @polyglot if defined?(@polyglot)
                        @polyglot = Ohcount::Detector.detect(self) if file?
                end

[Source]

# File lib/ohcount/source_file.rb, line 104
                def raw_entities(&block)
                        polyglot && Ohcount::parse_entities(contents, polyglot, &block)
                end

Yields a path to a physical file on disk containing the file contents. This is useful when a file absolutely must be referenced on disk. A temporary file will be created if an existing file is not available.

[Source]

# File lib/ohcount/source_file.rb, line 75
                def realize_file
                        raise ArgumentError.new('Missing block?') unless block_given?

                        if File.exist?(@filename)
                                yield @filename
                        elsif @file_location && File.basename(@file_location) == basename
                                yield @file_location
                        else
                                # No existing copy. Create a temporary file.
                                ScratchDir.new do |d|
                                        realized_filename = File.join(d,basename)
                                        File.open(realized_filename, "w") { |io| io.write(contents) }
                                        return yield(realized_filename)
                                end
                        end
                end

[Validate]