Created
September 22, 2012 17:57
-
-
Save ttscoff/3767188 to your computer and use it in GitHub Desktop.
Create directory trees from indented text input
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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