-
-
Save edwardloveall/5561850 to your computer and use it in GitHub Desktop.
ruby script to create a directory structure from indented data
This file contains hidden or 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 | |
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
The fork here removes the check for the number of arguments to be equal to the number of placeholder variables, similar to Textmate's snippet syntax. This makes it possible to use a variable twice. For example:
By just running
planter template name