Commit 51697338 authored by Seth Chisamore's avatar Seth Chisamore Committed by GitHub
Browse files

Merge pull request #795 from enfence/file-fetcher

Added file fetcher
parents 305419dd 4373ff56
......@@ -67,6 +67,7 @@ module Omnibus
autoload :NetFetcher, "omnibus/fetchers/net_fetcher"
autoload :NullFetcher, "omnibus/fetchers/null_fetcher"
autoload :PathFetcher, "omnibus/fetchers/path_fetcher"
autoload :FileFetcher, "omnibus/fetchers/file_fetcher"
autoload :ArtifactoryPublisher, "omnibus/publishers/artifactory_publisher"
autoload :NullPublisher, "omnibus/publishers/null_publisher"
......
......@@ -193,6 +193,8 @@ module Omnibus
GitFetcher
elsif source[:path]
PathFetcher
elsif source[:file]
FileFetcher
end
else
NullFetcher
......
#
# Copyright 2012-2014 Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "fileutils"
module Omnibus
class FileFetcher < Fetcher
#
# Fetch if the local file checksum is different than the path file
# checksum.
#
# @return [true, false]
#
def fetch_required?
target_shasum != destination_shasum
end
#
# The version identifier for this file. This is computed using the file
# on disk to the source and the shasum of that file on disk.
#
# @return [String]
#
def version_guid
"file:#{source_file}"
end
#
# Clean the given path by removing the project directory.
#
# @return [true, false]
# true if the directory was cleaned, false otherwise.
# Since we do not currently use the cache to sync files and
# always fetch from source, there is no need to clean anything.
# The fetch step (which needs to be called before clean) would
# have already removed anything extraneous.
#
def clean
true
end
#
# Fetch any new files by copying them to the +project_dir+.
#
# @return [void]
#
def fetch
log.info(log_key) { "Copying from `#{source_file}'" }
create_required_directories
FileUtils.cp(source_file, target_file)
# Reset target shasum on every fetch
@target_shasum = nil
target_shasum
end
#
# The version for this item in the cache. The is the shasum of the file
# on disk.
#
# This method is called *before* clean but *after* fetch. Since fetch
# automatically cleans, target vs. destination sha doesn't matter. Change this
# if that assumption changes.
#
# @return [String]
#
def version_for_cache
"file:#{source_file}|shasum:#{destination_shasum}"
end
#
# @return [String, nil]
#
def self.resolve_version(version, source)
version
end
private
#
# The path on disk to pull the file from.
#
# @return [String]
#
def source_file
source[:file]
end
#
# The path on disk where the file is stored.
#
# @return [String]
#
def target_file
File.join(project_dir, File.basename(source_file))
end
#
# The shasum of the file **inside** the project.
#
# @return [String, nil]
#
def target_shasum
@target_shasum ||= digest(target_file, :sha256)
rescue Errno::ENOENT
@target_shasum = nil
end
#
# The shasum of the file **outside** of the project.
#
# @return [String]
#
def destination_shasum
@destination_shasum ||= digest(source_file, :sha256)
end
end
end
require "spec_helper"
module Omnibus
describe FileFetcher do
include_examples "a software"
let(:source_file) { File.join(tmp_path, "t", "software") }
let(:target_file) { File.join(project_dir, "software") }
let(:source) do
{ file: source_file }
end
let(:manifest_entry) do
double(Omnibus::ManifestEntry,
name: "pathelogical",
locked_version: nil,
described_version: nil,
locked_source: source)
end
subject { described_class.new(manifest_entry, project_dir, build_dir) }
describe "#fetch_required?" do
context "when the files have different hashes" do
before do
create_file(source_file) { "different" }
create_file(target_file) { "same" }
end
it "return true" do
expect(subject.fetch_required?).to be_truthy
end
end
context "when the files have the same hash" do
before do
create_file(source_file) { "same" }
create_file(target_file) { "same" }
end
it "returns false" do
expect(subject.fetch_required?).to be(false)
end
end
end
describe "#version_guid" do
it "includes the source file" do
expect(subject.version_guid).to eq("file:#{source_file}")
end
end
describe "#fetch" do
before do
create_file(source_file)
remove_file(target_file)
end
it "fetches new files" do
subject.fetch
expect(target_file).to be_a_file
end
end
describe "#clean" do
it "returns true" do
expect(subject.clean).to be_truthy
end
end
describe "#version_for_cache" do
before do
create_file(source_file)
end
let(:sha) { "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }
it "includes the source_file and shasum" do
expect(subject.version_for_cache).to eq("file:#{source_file}|shasum:#{sha}")
end
end
describe "#resolve_version" do
it "just returns the version" do
expect(NetFetcher.resolve_version("1.2.3", source)).to eq("1.2.3")
end
end
end
end
require "spec_helper"
module Omnibus
describe FileFetcher do
let(:source_file) { "/local/file" }
let(:target_file) { "/project/dir/file" }
let(:project_dir) { "/project/dir" }
let(:build_dir) { "/build/dir" }
let(:manifest_entry) do
double(ManifestEntry,
name: "software",
locked_version: nil,
described_version: nil,
locked_source: { file: source_file })
end
subject { described_class.new(manifest_entry, project_dir, build_dir) }
describe "#fetch_required?" do
context "when the SHAs match" do
before do
allow(subject).to receive(:target_shasum).and_return("abcd1234")
allow(subject).to receive(:destination_shasum).and_return("abcd1234")
end
it "returns false" do
expect(subject.fetch_required?).to be(false)
end
end
context "when the SHAs do not match" do
before do
allow(subject).to receive(:target_shasum).and_return("abcd1234")
allow(subject).to receive(:destination_shasum).and_return("efgh5678")
end
it "returns true" do
expect(subject.fetch_required?).to be_truthy
end
end
end
describe "#version_guid" do
it "returns the path" do
expect(subject.version_guid).to eq("file:#{source_file}")
end
end
describe "#clean" do
it "returns true" do
expect(subject.clean).to be_truthy
end
end
describe "#fetch" do
before do
allow(subject).to receive(:create_required_directories)
end
it "copies the new files over" do
expect(FileUtils).to receive(:cp).with(source_file, target_file)
subject.fetch
end
end
describe "#version_for_cache" do
let(:shasum) { "abcd1234" }
before do
allow(subject).to receive(:digest)
.with(source_file, :sha256)
.and_return(shasum)
end
it "returns the shasum of the source file" do
expect(subject.version_for_cache).to eq("file:#{source_file}|shasum:#{shasum}")
end
end
end
end
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment