class Cir::Repository

Main database with tracked files and such.

Constants

FILE_LIST

Outside of the git repository we also have separate database of all files that we're tracking with additional metadata stored in this yaml file.

Public Class Methods

create(rootPath) click to toggle source

Create new repository backend (initialize git repo and the metadata database)

# File lib/cir/repository.rb, line 26
def self.create(rootPath)
  git = Cir::GitRepository.create(rootPath)

  # Create database
  database = YAML::Store.new(rootPath + '/' + FILE_LIST)
  database.transaction do
    database[:version] = 1
    database[:files] = {} 
  end

  # Add it to git and finish
  git.add_file FILE_LIST
  git.commit
end
new(rootPath) click to toggle source

Load repository (must exists) from given path.

# File lib/cir/repository.rb, line 43
def initialize(rootPath)
  # Database with files and their characteristics
  @git = Cir::GitRepository.new(rootPath)
  @database = YAML::Store.new(rootPath + '/' + FILE_LIST)
end

Public Instance Methods

deregister(files, options = {}) click to toggle source

Deregister file

Options

:message -> optional git message that should be used
# File lib/cir/repository.rb, line 77
def deregister(files, options = {})
  @database.transaction do
    expand(files) do |file|
      stored = stored_file(file)

      # Remove the file from git, our database and finally from git working directory
      FileUtils.rm(stored.repository_location)
      @git.remove_file(file[1..-1]) # Removing leading "/" to make the absolute path relative to the repository's root
      @database[:files].delete(file)

      puts "Deregistering file: #{file}"
    end
  end

  # And finally commit the transaction
  @git.commit(options[:message])
end
register(files, options = {}) click to toggle source

Register new file. Given path must be absolute.

Options

:message -> optional git message that should be used
# File lib/cir/repository.rb, line 54
def register(files, options = {})
  expand(files) do |file|
    # Register is one time operation, one can't re-register existing file
    raise Cir::Exception::AlreadyRegistered, file if registered?(file)

    # Import file to repository
    import_file file

    # Create new metadata for the tracked file
    @database.transaction { @database[:files][file] = {} }

    puts "Registering file: #{file}"
  end

  # And finally commit the transaction
  @git.commit(options[:message])
end
registered?(file) click to toggle source

Returns true if given file is registered, otherwise false.

# File lib/cir/repository.rb, line 98
def registered?(file)
  @database.transaction { return @database[:files][file] != nil }
end
restore(requested_files = nil, force = false) click to toggle source

Restore persistent variant of the files

# File lib/cir/repository.rb, line 128
def restore(requested_files = nil, force = false)
  generate_file_list(requested_files).each do |file|
    # If the destination file doesn't exist, we will simply copy it over
    if not File.exists?(file.file_path)
      FileUtils.cp(file.repository_location, file.file_path)
      puts "Restoring #{file.file_path}"
      next
    end

    # Skipping files that did not changed
    next unless file.diff.changed?

    # If we're run with force or in case of specific files, remove existing file and replace it
    if force or not requested_files.nil?
      FileUtils.remove_entry(file.file_path)
      FileUtils.cp(file.repository_location, file.file_path)
      puts "Restoring #{file.file_path}"
    else
      puts "Skipped mass change to #{key}."
    end
  end
end
status(requested_files = nil) click to toggle source

Return status for all registered files

# File lib/cir/repository.rb, line 104
def status(requested_files = nil)
  generate_file_list(requested_files)
end
update(requested_files = nil, options = {}) click to toggle source

Will update stored variant of existing files with their newer copy

Options

:message -> optional git message that should be used
# File lib/cir/repository.rb, line 114
def update(requested_files = nil, options = {})
  generate_file_list(requested_files).each do |file|
    if file.diff.changed?
      import_file(file.file_path)
      puts "Updating #{file.file_path}"
    end
  end

  # Finally commit the transaction
  @git.commit(options[:message])
end

Private Instance Methods

expand(files) { |expanded| ... } click to toggle source

Loop over user specified file paths that will always expand the specified path

# File lib/cir/repository.rb, line 202
def expand(files)
  files.each do |file|
    expanded = File.expand_path(file)
    yield expanded
  end
end
generate_file_list(requested_files) click to toggle source

Prepare file list for commands that accepts multiple files or none at all

# File lib/cir/repository.rb, line 155
def generate_file_list(requested_files)
  files = []

  @database.transaction do
    if requested_files.nil?
      # No file list, go over all files and detect if they changed
      @database[:files].each { |file, value| files << stored_file(file) }
    else
      # User supplied set of files
      expand(requested_files) { |file| files << stored_file(file) }
    end
  end

  files
end
import_file(file) click to toggle source

Import given file to git repository and add it to index

# File lib/cir/repository.rb, line 183
def import_file(file)
  target_file = File.expand_path(@git.repository_root + "/" + file)
  target_dir = File.dirname(target_file)

  if File.exists?(target_file)
    FileUtils.rm_rf(target_file, secure: true)
  else
    FileUtils.mkdir_p(target_dir)
  end

  # And finally copy the file to repository
  FileUtils.cp(file, target_file)

  # And register it inside git and our metadata database
  @git.add_file(file[1..-1]) # Removing leading "/" to make the absolute path relative to the repository's root
end
stored_file(file) click to toggle source

Create stored file entity for given file (full path)

# File lib/cir/repository.rb, line 172
def stored_file(file)
  raise Cir::Exception::NotRegistered, file unless @database[:files].include? file

  return Cir::StoredFile.new(
    file_path: file,
    repository_location: File.expand_path(@git.repository_root + "/" + file)
  )
end