Skip to content

Instantly share code, notes, and snippets.

@ggrandes
Last active November 26, 2019 19:48
Show Gist options
  • Save ggrandes/f89acda50fd794ebf77d to your computer and use it in GitHub Desktop.
Save ggrandes/f89acda50fd794ebf77d to your computer and use it in GitHub Desktop.
Extract files and scripts from Markdown CodeBlocks for Bootstraping
#!/usr/bin/perl -wT
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Original Source:
# https://gist.github.com/ggrandes/f89acda50fd794ebf77d
#
# Extract files and scripts from Markdown CodeBlocks
#
# Usage:
#
# curl -L https://gist.github.com/user/XXXXXX/raw > /tmp/file.md
# ./bs.pl < /tmp/file.md > /tmp/scripted-batch.sh
# . /tmp/scripted-batch.sh
#
# Format is:
# ```bash
# ### FILE NEW: /tmp/new-file.sh (0755:root:root)
# xxxxx
# ```
#
# ```
# ### FILE OVERWRITE: /tmp/overwrite-file (0755:root:root)
# xxxxx
# ```
#
# ```
# ### FILE SCRIPT: /tmp/p2 (0644:root:root)
# sed -e 's///g' < /tmp/p1 > /tmp/p2
# ```
#
use strict;
my $inCodeBlock = 0;
my $inHeaderCodeBlock = 0;
my $takeCodeBlock = 0;
my $data = {};
my $TAGENDFILE = "ENDFILE" . time;
print "#!/bin/bash", "\n";
while (<STDIN>) {
s/[\r\n]//g;
# Split Code Blocks
my $codeBlock = chr(0x60) . chr(0x60) . chr(0x60); # ```
if (m{^$codeBlock}) {
if ($takeCodeBlock) {
if ($data->{'type'} ne "SCRIPT") {
print $TAGENDFILE, "\n";
}
my $file = $data->{'file'};
my $perm = $data->{'perm'};
my $user = $data->{'user'};
my $group = $data->{'group'};
print '[ -e "', $file, '" ] && chmod ' , $perm, " ", $file, "\n";
print '[ -e "', $file, '" ] && chown ' , $user, ":", $group, " ", $file, "\n";
print ")", "\n"; # end subshell
print "###### ENDCODE ######", "\n";
}
$inCodeBlock = ($inCodeBlock ? 0 : 1); # swap state
$inHeaderCodeBlock = ($inCodeBlock ? 1 : 0);
$takeCodeBlock = 0;
$data = {};
next;
}
# Extract Code from Blocks
if ($inCodeBlock) {
if ($inHeaderCodeBlock) {
$inHeaderCodeBlock = 0;
if (m{^### FILE (NEW|OVERWRITE|SCRIPT): ([^ ]+) \((\d+):(\w+):(\w+)\)}) {
my ($type, $file, $perm, $user, $group) = ($1, $2, $3, $4, $5);
$takeCodeBlock = 1;
$data = {
type => $type,
file => $file,
perm => $perm,
user => $user,
group => $group
};
print "\n";
print "## ", join(" ", $type, $file, $perm, $user, $group), "\n";
print "###### BEGINCODE ######", "\n";
print "(", "\n"; # begin subshell
if ($data->{'type'} ne "SCRIPT") {
print "test -e ", $file, " && exit 0 # No overwrite\n" if ($data->{'type'} eq "NEW");
print "touch " , $file, "\n";
print "cat >" , $file, ' <<"', $TAGENDFILE, '"', "\n";
}
next;
}
}
}
if ($takeCodeBlock) {
# Skip empty lines in the beggining of file/script
if ($takeCodeBlock == 1) {
next if (m{^$} || m{^[ \t]+$});
$takeCodeBlock++;
}
print $_, "\n";
}
}
print "/bin/true", "\n";
exit 0;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment