summaryrefslogtreecommitdiff
path: root/bin/normalise-mrconfig
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2019-07-29 22:40:52 +0100
committerSean Whitton <spwhitton@spwhitton.name>2019-07-29 22:53:14 +0100
commit41adf257e02082159d753aa73ae139664ef60cec (patch)
tree35935202baf84f1163b9892da48d8291a0f66d6e /bin/normalise-mrconfig
parent9f3efd212ec39b2ebf62aacd794850fcbcb2f546 (diff)
downloaddotfiles-41adf257e02082159d753aa73ae139664ef60cec.tar.gz
use normalise-mrconfig instead of a symlink
This means we can get rid of chain loading of ~/src/.mrconfig, which has various issues.
Diffstat (limited to 'bin/normalise-mrconfig')
-rwxr-xr-xbin/normalise-mrconfig95
1 files changed, 95 insertions, 0 deletions
diff --git a/bin/normalise-mrconfig b/bin/normalise-mrconfig
new file mode 100755
index 00000000..20ad333b
--- /dev/null
+++ b/bin/normalise-mrconfig
@@ -0,0 +1,95 @@
+#!/usr/bin/env perl
+
+# normalise-mrconfig -- regenerate ~/.mrconfig
+
+# Copyright (C) 2019 Sean Whitton
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or (at
+# your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+
+# This script must be as portable as possible (inc. its shebang).
+
+use strict;
+use warnings;
+use autodie;
+
+sub blocks_from_file ($);
+sub say_block (*$$);
+
+exit main();
+
+sub main {
+ my $master = $ENV{HOME} . "/src/dotfiles/.mrconfig.in";
+ my $target = $ENV{HOME} . "/.mrconfig";
+
+ unlink $target unless -f $target;
+
+ my %master_blocks = blocks_from_file($master);
+ my %target_blocks = -f $target ? blocks_from_file($target) : undef;
+ for (keys %master_blocks) {
+ $master_blocks{$_} = "# DO NOT EDIT THIS BLOCK; automatically updated\n"
+ . join "\n", grep !/^\s*#/, grep !/^\s*$/,
+ split "\n", $master_blocks{$_};
+ }
+ for (keys %target_blocks) {
+ delete $target_blocks{$_} if exists $master_blocks{$_};
+ }
+
+ open my $fh, '>', $target;
+ print $fh "# -*- mode: conf -*-\n";
+
+ # any DEFAULT has to come first to have effect on the proceding
+ # blocks
+ if (defined $master_blocks{"DEFAULT"}) {
+ say_block($fh, "DEFAULT", $master_blocks{"DEFAULT"});
+ delete $master_blocks{"DEFAULT"};
+ } elsif (defined $target_blocks{"DEFAULT"}) {
+ say_block($fh, "DEFAULT", $target_blocks{"DEFAULT"});
+ delete $target_blocks{"DEFAULT"};
+ }
+ # put the master blocks in first, so that by default mr processes
+ # those repos first
+ say_block($fh, $_, $master_blocks{$_}) foreach keys %master_blocks;
+ # finally, remaining target blocks
+ say_block($fh, $_, $target_blocks{$_}) foreach keys %target_blocks;
+
+ return 0;
+}
+
+sub blocks_from_file ($) {
+ my $file = shift;
+
+ my %blocks;
+ my $current_block;
+ open my $fh, '<', $file;
+ while (<$fh>) {
+ if (/^\[(.+)\]$/) {
+ $current_block = $1;
+ } elsif (defined $current_block) {
+ $blocks{$current_block} .= $_;
+ }
+ }
+ # drop trailing newlines from the text of each block
+ { local $/ = ''; chomp $blocks{$_} foreach keys %blocks }
+ return %blocks;
+}
+
+sub say_block (*$$) {
+ my ($fh, $block, $text) = @_;
+
+ print $fh "\n[$block]\n";
+ print $fh $text;
+ print $fh "\n";
+}