Class: LabelWeaver::TempRepo

Inherits:
Object
  • Object
show all
Defined in:
lib/label_weaver/temp_repo.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(repository_path, repository_url:, branch: "main", excluded_upstream_files: [], forced_upstream_files: [], logger: Logger.new($stdout)) ⇒ TempRepo

Returns a new instance of TempRepo.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# File 'lib/label_weaver/temp_repo.rb', line 12

def initialize(
  repository_path,
  repository_url:,
  branch: "main",
  excluded_upstream_files: [],
  forced_upstream_files: [],
  logger: Logger.new($stdout)
)
  @repository_path = repository_path
  @repository_url = repository_url
  @branch = branch
  @excluded_upstream_files = excluded_upstream_files + %w[. .. .git/**]
  @forced_upstream_files = forced_upstream_files
  @logger = logger
end

Instance Attribute Details

#branchObject (readonly)

Returns the value of attribute branch.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def branch
  @branch
end

#excluded_upstream_filesObject (readonly)

Returns the value of attribute excluded_upstream_files.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def excluded_upstream_files
  @excluded_upstream_files
end

#forced_upstream_filesObject (readonly)

Returns the value of attribute forced_upstream_files.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def forced_upstream_files
  @forced_upstream_files
end

#loggerObject (readonly)

Returns the value of attribute logger.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def logger
  @logger
end

#repository_pathObject (readonly) Also known as: root_path

Returns the value of attribute repository_path.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def repository_path
  @repository_path
end

#repository_urlObject (readonly)

Returns the value of attribute repository_url.



10
11
12
# File 'lib/label_weaver/temp_repo.rb', line 10

def repository_url
  @repository_url
end

Instance Method Details

#changed_file?(repository_file, project_root_dir:) ⇒ Boolean

Returns:

  • (Boolean)


41
42
43
# File 'lib/label_weaver/temp_repo.rb', line 41

def changed_file?(repository_file, project_root_dir:)
  digest_for(repository_file) != digest_for(project_root_dir + relative_path(repository_file))
end

#clone_or_update(always_clone: false) ⇒ Object

Clones the repository if it doesn’t exist yet locally or fetches the latest updates



48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/label_weaver/temp_repo.rb', line 48

def clone_or_update(always_clone: false)
  if always_clone
    logger.info "Set to always clone the repository. Deleting any previously checked out version..."
    FileUtils.rm_rf(repository_path)
  end

  if repository_path.exist?
    logger.info "Pulling latest changes from remote repository (#{repository_url})..."

    repo.pull("origin", branch)
  else
    logger.info "Cloning remote repository, this might take a while..."

    Git.clone(
      repository_url,
      repository_path.basename,
      path: repository_path.parent,
      branch:
    )
  end
end

#digest_for(file) ⇒ Object



37
38
39
# File 'lib/label_weaver/temp_repo.rb', line 37

def digest_for(file)
  Util.digest(file)
end

#excluded_file?(repository_file) ⇒ Boolean

Returns true if the file should never be copied over from the repository.

Returns:

  • (Boolean)

    true if the file should never be copied over from the repository



85
86
87
# File 'lib/label_weaver/temp_repo.rb', line 85

def excluded_file?(repository_file)
  excluded_upstream_files.any? { relative_path(repository_file).fnmatch?(_1, File::FNM_DOTMATCH) }
end

#forced_file?(repository_file) ⇒ Boolean

Returns true if the file should always be copied over from the repository.

Returns:

  • (Boolean)

    true if the file should always be copied over from the repository



92
93
94
# File 'lib/label_weaver/temp_repo.rb', line 92

def forced_file?(repository_file)
  forced_upstream_files.any? { relative_path(repository_file).fnmatch?(_1, File::FNM_DOTMATCH) }
end

#relative_path(filename) ⇒ Pathname

Returns the filename relative to the git repository root.

Returns:

  • (Pathname)

    the filename relative to the git repository root



112
113
114
# File 'lib/label_weaver/temp_repo.rb', line 112

def relative_path(filename)
  filename.relative_path_from(repository_path)
end

#relevant_filesArray<Pathname>

Returns All repository files that are not set to be excluded.

Returns:

  • (Array<Pathname>)

    All repository files that are not set to be excluded



73
74
75
76
77
78
79
80
# File 'lib/label_weaver/temp_repo.rb', line 73

def relevant_files
  files.filter do |file|
    # Reject any files that are set up to be excluded. Shell filename globbing rules apply
    next false if excluded_file?(file)

    true
  end
end

#relevant_files_with_project_files(project_root_dir:) ⇒ Array<Array<Pathname, Pathname>>

Returns all relevant repository files with their corresponding path within the project.

Returns:

  • (Array<Array<Pathname, Pathname>>)

    all relevant repository files with their corresponding path within the project



120
121
122
123
124
125
# File 'lib/label_weaver/temp_repo.rb', line 120

def relevant_files_with_project_files(project_root_dir:)
  relevant_files.map do |repository_file|
    relative_filename = relative_path(repository_file)
    [repository_file, project_root_dir + relative_filename]
  end
end

#timestamp_for(file) ⇒ Time

Returns the last time the file was part of a commit, closest we can get to an mtime.

Returns:

  • (Time)

    the last time the file was part of a commit, closest we can get to an mtime



33
34
35
# File 'lib/label_weaver/temp_repo.rb', line 33

def timestamp_for(file)
  repo.log(1).path(file).first.date
end

#update_repository_timestampsObject

Updates the atime and mtime of each file in the repository to their latest commit time TODO: Check if still needed



100
101
102
103
104
105
106
107
# File 'lib/label_weaver/temp_repo.rb', line 100

def update_repository_timestamps
  logger.info "Updating repository timestamps..."
  repository_path.glob("**/*", File::FNM_DOTMATCH).each do |file|
    # Set the file modification times to the last time they were updated in a commit
    time = repo.all.log.path(file).first.date
    file.utime(time, time)
  end
end