Create directory trees from indented text input
#!/usr/bin/ruby | |
=begin | |
Planter v1.3 | |
Brett Terpstra 2013 | |
ruby script to create a directory structure from indented data. | |
Three ways to use it: | |
- Pipe indented (tabs or 2 spaces) text to the script | |
- e.g. `cat "mytemplate" | planter.rb | |
- Create template.tpl files in ~/.planter and call them by their base name | |
- e.g. Create a text file in ~/.planter/site.tpl | |
- `planter.rb site` | |
- Call planter.rb without input and it will open your $EDITOR to create the tree on the fly | |
You can put %%X%% variables into templates, where X is a number that corresponds to the index | |
of the argument passed when planter is called. e.g. `planter.rb client "Mr. Butterfinger"` | |
would replace %%1%% in client.tpl with "Mr. Butterfinger". Use %%X|default%% to make a variable | |
optional with default replacement. | |
If a line in the template matches a file or folder that exists in ~/.planter, that file/folder | |
will be copied to the destination folder. | |
=end | |
require 'yaml' | |
require 'tmpdir' | |
require 'fileutils' | |
def get_hierarchy(input,parent=".",dirs_to_create=[]) | |
input.each do |dirs| | |
if dirs.kind_of? Hash | |
dirs.each do |k,v| | |
dirs_to_create.push(File.expand_path("#{parent}/#{k.strip}")) | |
dirs_to_create = get_hierarchy(v,"#{parent}/#{k.strip}",dirs_to_create) | |
end | |
elsif dirs.kind_of? Array | |
dirs_to_create = get_hierarchy(dirs,parent,dirs_to_create) | |
elsif dirs.kind_of? String | |
dirs_to_create.push(File.expand_path("#{parent}/#{dirs.strip}")) | |
end | |
end | |
return dirs_to_create | |
end | |
def text_to_yaml(input, replacements = []) | |
variables_count = input.scan(/%%\d+%%/).length | |
if variables_count > replacements.length | |
$stderr.puts('Mismatch variable/replacement counts!') | |
$stderr.puts("Template has #{variables_count} required replacements, #{replacements.length} provided.") | |
Process.exit 1 | |
end | |
input.gsub!(/%%(\d+)(?:\|(.*?))?%%/) do |match| | |
if replacements[$1.to_i - 1] | |
replacements[$1.to_i - 1] | |
elsif !$2.nil? | |
$2 | |
else | |
print "Invalid variable" | |
Process.exit 1 | |
end | |
end | |
lines = input.split(/[\n\r]/) | |
output = [] | |
prev_indent = 0 | |
lines.each_with_index do |line, i| | |
indent = line.gsub(/ /,"\t").match(/(\t*).*$/)[1] | |
if indent.length > prev_indent | |
lines[i-1] = lines[i-1].chomp + ":" | |
end | |
prev_indent = indent.length | |
lines[i] = indent.gsub(/\t/,' ') + "- " + lines[i].strip # unless indent.length == 0 | |
end | |
lines.delete_if {|line| | |
line == '' | |
} | |
return "---\n" + lines.join("\n") | |
end | |
if STDIN.stat.size > 0 | |
data = STDIN.read | |
elsif ARGV.length > 0 | |
template = File.expand_path("~/.planter/#{ARGV[0].gsub(/\.tpl$/,'')}.tpl") | |
ARGV.shift | |
if File.exists? template | |
File.open(template, 'r') do |infile| | |
data = infile.read | |
end | |
else | |
puts "Specified template not found in ~/.planter/*.tpl" | |
end | |
else | |
tmpfile = File.expand_path(Dir.tmpdir + "/planter.tmp") | |
File.new(tmpfile, 'a+') | |
# at_exit {FileUtils.rm(tmpfile) if File.exists?(tmpfile)} | |
%x{$EDITOR "#{tmpfile}"} | |
data = "" | |
File.open(tmpfile, 'r') do |infile| | |
data = infile.read | |
end | |
end | |
data.strip! | |
yaml = YAML.load(text_to_yaml(data,ARGV)) | |
dirs_to_create = get_hierarchy(yaml) | |
dirs_to_create.each do |dir| | |
curr_dir = ENV['PWD'] | |
unless File.exists? dir | |
$stderr.puts "Creating #{dir.sub(/^#{curr_dir}\//,'')}" | |
if File.exists?(File.join(File.expand_path("~/.planter"),File.basename(dir))) | |
FileUtils.cp_r(File.join(File.expand_path("~/.planter"),File.basename(dir)), dir) | |
else | |
Dir.mkdir(dir) | |
end | |
else | |
$stderr.puts "Skipping #{dir.sub(/^#{curr_dir}\//,'')} (file exists)" | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment