Skip to content

Commit

Permalink
Support executable templates
Browse files Browse the repository at this point in the history
  • Loading branch information
nabertrand committed Nov 3, 2023
1 parent 4e46ce2 commit 30a105a
Show file tree
Hide file tree
Showing 6 changed files with 50 additions and 9 deletions.
9 changes: 7 additions & 2 deletions lib/pdk/module/convert.rb
Original file line number Diff line number Diff line change
Expand Up @@ -148,20 +148,25 @@ def stage_changes!(context = PDK.context)
module_name = new_metadata.nil? ? 'new-module' : new_metadata.data['name']
metadata_for_render = new_metadata.nil? ? {} : new_metadata.data

template_dir.render_new_module(module_name, metadata_for_render) do |relative_file_path, file_content, file_status|
template_dir.render_new_module(module_name, metadata_for_render) do |relative_file_path, file_content, file_status, file_executable|
absolute_file_path = File.join(module_dir, relative_file_path)
case file_status
when :unmanage
PDK.logger.debug(format("skipping '%{path}'", path: absolute_file_path))
when :delete
update_manager.remove_file(absolute_file_path)
when :init
update_manager.add_file(absolute_file_path, file_content) if convert? && !PDK::Util::Filesystem.exist?(absolute_file_path)
if convert? && !PDK::Util::Filesystem.exist?(absolute_file_path)
update_manager.add_file(absolute_file_path, file_content)
update_manager.make_file_executable(absolute_file_path) if file_executable
end
when :manage
if PDK::Util::Filesystem.exist?(absolute_file_path)
update_manager.modify_file(absolute_file_path, file_content)
update_manager.make_file_executable(absolute_file_path) if file_executable && !PDK::Util::Filesystem.executable?(absolute_file_path)
else
update_manager.add_file(absolute_file_path, file_content)
update_manager.make_file_executable(absolute_file_path) if file_executable
end
end
end
Expand Down
30 changes: 27 additions & 3 deletions lib/pdk/module/update_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ def initialize
@modified_files = Set.new
@added_files = Set.new
@removed_files = Set.new
@executable_files = Set.new
@diff_cache = {}
end

Expand All @@ -37,6 +38,13 @@ def remove_file(path)
@removed_files << path
end

# Store a pending file execute mode change.
#
# @param path [String] The path to the file to be made executable.
def make_file_executable(path)
@executable_files << path
end

# Generate a summary of the changes that will be applied to the module.
#
# @raise (see #calculate_diffs)
Expand All @@ -49,7 +57,8 @@ def changes
{
added: @added_files,
removed: @removed_files.select { |f| PDK::Util::Filesystem.exist?(f) },
modified: @diff_cache.compact
modified: @diff_cache.compact,
'made executable': @executable_files
}
end

Expand All @@ -60,7 +69,8 @@ def changes
def changes?
!changes[:added].empty? ||
!changes[:removed].empty? ||
changes[:modified].any? { |_, value| !value.nil? }
changes[:modified].any? { |_, value| !value.nil? } ||
!changes[:'made executable'].empty?
end

# Check if the update manager will change the specified file upon sync.
Expand All @@ -72,13 +82,15 @@ def changes?
def changed?(path)
changes[:added].any? { |add| add[:path] == path } ||
changes[:removed].include?(path) ||
changes[:modified].key?(path)
changes[:modified].key?(path) ||
changes[:'made executable'].include?(path)
end

def clear!
@modified_files.clear
@added_files.clear
@removed_files.clear
@executable_files.clear
nil
end

Expand All @@ -100,6 +112,10 @@ def sync_changes!
files_to_write.each do |file|
write_file(file[:path], file[:content])
end

@executable_files.each do |file|
update_execute_bits(file)
end
end

# Remove a file from disk.
Expand Down Expand Up @@ -215,6 +231,14 @@ def unified_diff(path, old_content, new_content, lines_of_context = 3)

output.join($INPUT_RECORD_SEPARATOR)
end

# Set the execute bits on a file
def update_execute_bits(path)
require 'pdk/util/filesystem'

PDK.logger.debug(format("making '%{path}' executable", path: path))
PDK::Util::Filesystem.make_executable(path)
end
end
end
end
2 changes: 1 addition & 1 deletion lib/pdk/template/renderer/v1/legacy_template_dir.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def config_for(dest_path, sync_config_path = nil)
@config = conf_defaults
@config.deep_merge!(@sync_config, knockout_prefix: '---') unless @sync_config.nil?
end
file_config = @config.fetch(:global, {})
file_config = @config.fetch('common', {}).clone
file_config['module_metadata'] = @module_metadata
file_config.merge!(@config.fetch(dest_path, {})) unless dest_path.nil?
file_config.merge!(@config).tap do |c|
Expand Down
4 changes: 3 additions & 1 deletion lib/pdk/template/renderer/v1/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,9 @@ def render_module(options = {})
end
end

yield dest_path, dest_content, dest_status
dest_executable = config['manage_execute_permissions'] && PDK::Util::Filesystem.executable?(File.join(template_loc, template_file))

yield dest_path, dest_content, dest_status, dest_executable
end
end
# :nocov:
Expand Down
10 changes: 10 additions & 0 deletions lib/pdk/util/filesystem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@ def read_file(file, nil_on_error: false, open_args: 'r')
end
module_function :read_file

def make_executable(file)
FileUtils.chmod('a+x', file)
end
module_function :make_executable

# :nocov:
# These methods just wrap core Ruby functionality and
# can be ignored for code coverage
Expand Down Expand Up @@ -133,6 +138,11 @@ def mv(*args, **kwargs)
end
end
module_function :mv

def executable?(*args)
File.executable?(*args)
end
module_function :executable?
# :nocov:
end
end
Expand Down
4 changes: 2 additions & 2 deletions spec/unit/pdk/module/convert_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def module_path(relative_path)
let(:update_manager) { instance_double(PDK::Module::UpdateManager, sync_changes!: true) }
let(:template_dir) { instance_double(PDK::Template::TemplateDir, metadata: {}) }
let(:metadata) { instance_double(PDK::Module::Metadata, data: {}) }
let(:template_files) { { path: 'a/path/to/file', content: 'file contents', status: :manage } }
let(:template_files) { { path: 'a/path/to/file', content: 'file contents', status: :manage, executable: false } }
let(:added_files) { Set.new }
let(:removed_files) { Set.new }
let(:modified_files) { {} }
Expand All @@ -100,7 +100,7 @@ def module_path(relative_path)
allow(instance).to receive(:update_metadata).with(any_args).and_return(metadata)
allow(PDK::Template).to receive(:with).with(anything, anything).and_yield(template_dir)
allow(PDK::Util::Git).to receive(:repo?).with(anything).and_return(true)
allow(template_dir).to receive(:render_new_module).and_yield(template_files[:path], template_files[:content], template_files[:status])
allow(template_dir).to receive(:render_new_module).and_yield(template_files[:path], template_files[:content], template_files[:status], template_files[:executable])
allow(update_manager).to receive(:changes).and_return(changes)
allow(update_manager).to receive(:changed?).with('Gemfile').and_return(false)
allow(update_manager).to receive(:unlink_file).with('Gemfile.lock')
Expand Down

0 comments on commit 30a105a

Please sign in to comment.