I have a template file that lets me bootstrap Rails skeletons with my preferred gems and run boilerplate generators and migrations. This works flawlessly apart from the addition of new files.
Currently Thor’s actions allow usage of file and create_file. But the problem I have with them is the source of the file itself has to be provided either inside the template itself or be read from an absolute location in the file system.
The way I saw it – it’d make more sense (to me) to add the static files (e.g. configs) next to the template file itself. The problem though is that during the generation I don’t have access to the location of the template itself. And getting it is rather cumbersome (I’d have to parse through ARGV and massage the path of the found -m value).
I added a PoC to Rails::Generators::Actions module that provides template_source_dir helper method to retrieve a folder of the currently used template as well as overrides the apply method to store the latest template directory for said helper to use:
def apply(path, config = {})
(@_template_path_stack ||= []) << (path =~ %r{^https?://}
? path
: File.expand_path(path))
super
ensure
@_template_path_stack.pop
end
def template_source_dir
return unless (path = @_template_path_stack&.last)
path =~ %r{^https?://} ?
URI(path).then { |u| "#{u.scheme}://#{u.host}#{File.dirname(u.path)}" } :
File.dirname(path)
end
I have tested this with the following template structure:
template/
template.rb # the rails app template file
tasks.json # my frequently used tasks in vscode-like editors
The template.rb had the following snippet inside:
tasks_json_path = File.join(template_source_dir, 'tasks.json')
tasks_json = File.read(tasks_json_path)
create_file '.vscode/tasks.json' do
tasks_json
end
I ran the rails app generator using my local rails checkout
ruby ./rails/railties/exe/rails new tpl-test -m ./template/template.rb
And it properly took the contents of tasks.json into the rails app.
Before doing tests with URLs and covering this with tests I’d like to know if anyone would be interested in this feature and/or consider it useful in general?
The two “meat” methods were generated by LLM.