#!/usr/bin/perl # # vim: ts=4:noet # # sboconfig # script to handle sbotools configuration # # authors: Jacob Pipkin # Luke Williams # Andreas Guldstrand # license: WTFPL use 5.16.0; use strict; use warnings FATAL => 'all'; use SBO::Lib qw/ slurp usage_error script_error $tempdir open_fh %config $conf_dir $conf_file show_version /; use File::Basename; use Getopt::Long qw(:config no_ignore_case_always); use File::Copy; use File::Path qw(make_path); use File::Temp qw(tempfile);; my $self = basename($0); sub show_usage { print <<"EOF"; Usage: $self [options] [arguments] Options: -h|--help: this screen. -v|--version: version information. -l|--list: show current options. Config options (defaults shown): -c|--clean FALSE: NOCLEAN: if TRUE, do NOT clean up after building by default. -d|--distclean FALSE: DISTCLEAN: if TRUE, DO clean distfiles by default after building. -j|--jobs FALSE: JOBS: numeric -j setting to feed to make for multicore systems. -p|--pkg-dir FALSE: PKG_DIR: set a directory to store packages in. -s|--sbo-home /usr/sbo: SBO_HOME: set the SBo directory. -o|--local-overrides FALSE: LOCAL_OVERRIDES: a directory containing local overrides. -V|--slackware-version FALSE: SLACKWARE_VERSION: use the SBo repository for this version. -r|--repo FALSE: REPO: use a repository other than SBo. EOF return 1; } my %options; GetOptions(\%options, 'help|h', 'version|v', 'list|l', 'noclean|c=s', 'distclean|d=s', 'jobs|j=s', 'pkg-dir|p=s', 'sbo-home|s=s', 'local-overrides|o=s', 'slackware-version|V=s', 'repo|r=s'); if ($options{help}) { show_usage(); exit 0 } if ($options{version}) { show_version(); exit 0 } my %valid_confs = ( noclean => 'NOCLEAN', distclean => 'DISTCLEAN', jobs => 'JOBS', 'pkg-dir' => 'PKG_DIR', 'sbo-home' => 'SBO_HOME', 'local-overrides' => 'LOCAL_OVERRIDES', 'slackware-version' => 'SLACKWARE_VERSION', 'repo' => 'REPO', ); my %params = ( NOCLEAN => 'c|--noclean', DISTCLEAN => 'd|--distclean', JOBS => 'j|--jobs', PKG_DIR => 'p|--pkg-dir', SBO_HOME => 's|--sbo-home', LOCAL_OVERRIDES => 'o|--local-overrides', SLACKWARE_VERSION => 'V|--slackware-version', REPO => 'r|--repo', ); if (exists $options{list}) { my @keys = sort {$a cmp $b} keys %config; say "sboconfig -$params{$_}:\n $_=$config{$_}" for @keys; exit 0; } if (not %options) { show_usage(); exit 0; } # setup what's being changed, sanity check. my %changes; for my $key (keys %valid_confs) { my $value = $valid_confs{$key}; $changes{$value} = $options{$key} if exists $options{$key}; } my $warn = 'You have provided an invalid parameter for'; if (exists $changes{NOCLEAN}) { usage_error("$warn -c") unless $changes{NOCLEAN} =~ /^(TRUE|FALSE)$/; } if (exists $changes{DISTCLEAN}) { usage_error("$warn -d") unless $changes{DISTCLEAN} =~ /^(TRUE|FALSE)$/; } if (exists $changes{JOBS}) { usage_error("$warn -j") unless $changes{JOBS} =~ /^(\d+|FALSE)$/; } if (exists $changes{PKG_DIR}) { usage_error("$warn -p") unless $changes{PKG_DIR} =~ qr#^(/|FALSE$)#; } if (exists $changes{SBO_HOME}) { usage_error("$warn -s") unless $changes{SBO_HOME} =~ qr#^(/|FALSE$)#; } if (exists $changes{LOCAL_OVERRIDES}) { usage_error("$warn -o") unless $changes{LOCAL_OVERRIDES} =~ qr#^(/|FALSE$)#; } if (exists $changes{SLACKWARE_VERSION}) { usage_error("$warn -V") unless $changes{SLACKWARE_VERSION} =~ m/^(\d+\.\d+|FALSE)$/; } sub config_write { script_error('config_write requires at least two arguments.') unless @_ >= 2; if (! -d $conf_dir) { mkdir $conf_dir or usage_error("Unable to create $conf_dir. Exiting."); } my $conf = slurp($conf_file) || ''; _fixup_conf($conf); while (@_ >= 2) { my $key = shift; my $val = shift; say "Setting $key to $val..."; if ($conf =~ /^\Q$key\E=/m) { $conf =~ s/^\Q$key\E=.*$/$key=$val/m; } else { $conf .= "$key=$val\n"; } } _fixup_conf($conf); my ($conffh, $exit) = open_fh($conf_file, '>'); if ($exit) { warn $conffh; exit $exit; } print {$conffh} $conf; } # make sure there are no duplicate keys in the config sub _fixup_conf { my @lines = split /\n/, $_[0]; my @fixed; my %keys; foreach my $line (@lines) { # if it's a comment or blank line, just pass it through if ($line =~ /^(#|\s*$)/) { push @fixed, $line; next; } my ($key, $val) = split /=/, $line; next if exists $keys{$key}; $keys{$key}++; push @fixed, $line; } $_[0] = join "\n", @fixed, ''; # make sure we end with a newline if there are any lines } config_write(%changes) if %changes; exit 0;