diff options
| author | Anton Bobov <anton@bobov.name> | 2023-08-05 23:48:19 +0500 |
|---|---|---|
| committer | Anton Bobov <anton@bobov.name> | 2023-08-05 23:48:19 +0500 |
| commit | 7fb714fadb768401b251a7584d76f216acf5943a (patch) | |
| tree | d1f85b5d5e74ac1c45ec4b956e8e851ce9469d6f | |
| parent | b25a5b794be7093dbcd556fcab2ebc50bb33e8b2 (diff) | |
Update scripts
| -rwxr-xr-x | bat.sh (renamed from bat) | 0 | ||||
| -rwxr-xr-x | battery-status.sh | 10 | ||||
| -rwxr-xr-x | clipboard-stream | 34 | ||||
| -rwxr-xr-x | diff-so-fancy | 1305 | ||||
| -rwxr-xr-x | pit-run | 144 | ||||
| -rwxr-xr-x | through-vpn.sh | 4 |
6 files changed, 177 insertions, 1320 deletions
diff --git a/battery-status.sh b/battery-status.sh index 8b7a057..3c4ac28 100755 --- a/battery-status.sh +++ b/battery-status.sh @@ -8,15 +8,15 @@ print_status() { [ $print_sepparator = true ] && printf ' ' case "$status" in - "Full") + "Full"|"Not charging") return;; "Discharging") - status="-";; + status="↓";; "Charging") - status="+";; + status="↑";; "Unknown") # Probably rich the threshold - if [ $(echo "$current_charge > 50" | bc -l) == 1 ] ; then + if [ "$(echo "$current_charge > 50" | bc -l)" == 1 ] ; then return fi status="?" @@ -25,7 +25,7 @@ print_status() { status="?";; esac - printf '%s %.0f%s' $(basename $bat) $current_charge "$status" + printf '%s %.0f%s' "$(basename "$bat")" "$current_charge" "$status" print_sepparator=true } diff --git a/clipboard-stream b/clipboard-stream index b4c1120..a1f0cdc 100755 --- a/clipboard-stream +++ b/clipboard-stream @@ -1,13 +1,29 @@ #!/bin/bash -set -e - -recent_value=$(xclip -o -selection clipboard) -while true ; do - value=$(xclip -o -selection clipboard) - if [ "$recent_value" != "$value" ] ; then - recent_value=$value - echo $recent_value +set -euo pipefail + +find_clipboard_command() { + if command -v xclip &>/dev/null; then + echo xclip -out -selection clipboard + elif command -v xsel &>/dev/null; then + echo xsel --output --clipboard + else + echo "No clipboard command found" >&2 + exit 1 + fi +} + +main() { + CLIPBOARD_COMMAND=$(find_clipboard_command) + recent_value=$(eval "$CLIPBOARD_COMMAND") + while true; do + value=$(eval "$CLIPBOARD_COMMAND") + if [ "$recent_value" != "$value" ]; then + recent_value=$value + echo "$recent_value" fi sleep 0.1 -done + done +} + +main "$@" diff --git a/diff-so-fancy b/diff-so-fancy deleted file mode 100755 index 7d33a34..0000000 --- a/diff-so-fancy +++ /dev/null @@ -1,1305 +0,0 @@ -#!/usr/bin/env perl - -# This chunk of stuff was generated by App::FatPacker. To find the original -# file's code, look for the end of this BEGIN block or the string 'FATPACK' -BEGIN { -my %fatpacked; - -$fatpacked{"DiffHighlight.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'DIFFHIGHLIGHT'; - package DiffHighlight; - - use 5.008; - use warnings FATAL => 'all'; - use strict; - - # Use the correct value for both UNIX and Windows (/dev/null vs nul) - use File::Spec; - - my $NULL = File::Spec->devnull(); - - # Highlight by reversing foreground and background. You could do - # other things like bold or underline if you prefer. - our @OLD_HIGHLIGHT = ( - color_config('color.diff-highlight.oldnormal', "\e[1;31m"), - color_config('color.diff-highlight.oldhighlight', "\e[1;31;48;5;52m"), - "\x1b[27m", - ); - our @NEW_HIGHLIGHT = ( - color_config('color.diff-highlight.newnormal', "\e[1;32m"), - color_config('color.diff-highlight.newhighlight', "\e[1;32;48;5;22m"), - $OLD_HIGHLIGHT[2], - ); - - - - my $RESET = "\x1b[m"; - my $COLOR = qr/\x1b\[[0-9;]*m/; - my $BORING = qr/$COLOR|\s/; - - my @removed; - my @added; - my $in_hunk; - my $graph_indent = 0; - - our $line_cb = sub { print @_ }; - our $flush_cb = sub { local $| = 1 }; - - # Count the visible width of a string, excluding any terminal color sequences. - sub visible_width { - local $_ = shift; - my $ret = 0; - while (length) { - if (s/^$COLOR//) { - # skip colors - } elsif (s/^.//) { - $ret++; - } - } - return $ret; - } - - # Return a substring of $str, omitting $len visible characters from the - # beginning, where terminal color sequences do not count as visible. - sub visible_substr { - my ($str, $len) = @_; - while ($len > 0) { - if ($str =~ s/^$COLOR//) { - next - } - $str =~ s/^.//; - $len--; - } - return $str; - } - - sub handle_line { - my $orig = shift; - local $_ = $orig; - - # match a graph line that begins a commit - if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space - $COLOR?\*$COLOR?[ ] # a "*" with its trailing space - (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|" - [ ]* # trailing whitespace for merges - /x) { - my $graph_prefix = $&; - - # We must flush before setting graph indent, since the - # new commit may be indented differently from what we - # queued. - flush(); - $graph_indent = visible_width($graph_prefix); - - } elsif ($graph_indent) { - if (length($_) < $graph_indent) { - $graph_indent = 0; - } else { - $_ = visible_substr($_, $graph_indent); - } - } - - if (!$in_hunk) { - $line_cb->($orig); - $in_hunk = /^$COLOR*\@\@ /; - } - elsif (/^$COLOR*-/) { - push @removed, $orig; - } - elsif (/^$COLOR*\+/) { - push @added, $orig; - } - else { - flush(); - $line_cb->($orig); - $in_hunk = /^$COLOR*[\@ ]/; - } - - # Most of the time there is enough output to keep things streaming, - # but for something like "git log -Sfoo", you can get one early - # commit and then many seconds of nothing. We want to show - # that one commit as soon as possible. - # - # Since we can receive arbitrary input, there's no optimal - # place to flush. Flushing on a blank line is a heuristic that - # happens to match git-log output. - if (!length) { - $flush_cb->(); - } - } - - sub flush { - # Flush any queued hunk (this can happen when there is no trailing - # context in the final diff of the input). - show_hunk(\@removed, \@added); - @removed = (); - @added = (); - } - - sub highlight_stdin { - while (<STDIN>) { - handle_line($_); - } - flush(); - } - - # Ideally we would feed the default as a human-readable color to - # git-config as the fallback value. But diff-highlight does - # not otherwise depend on git at all, and there are reports - # of it being used in other settings. Let's handle our own - # fallback, which means we will work even if git can't be run. - sub color_config { - my ($key, $default) = @_; - my $s = `git config --get-color $key 2>$NULL`; - return length($s) ? $s : $default; - } - - sub show_hunk { - my ($a, $b) = @_; - - # If one side is empty, then there is nothing to compare or highlight. - if (!@$a || !@$b) { - $line_cb->(@$a, @$b); - return; - } - - # If we have mismatched numbers of lines on each side, we could try to - # be clever and match up similar lines. But for now we are simple and - # stupid, and only handle multi-line hunks that remove and add the same - # number of lines. - if (@$a != @$b) { - $line_cb->(@$a, @$b); - return; - } - - my @queue; - for (my $i = 0; $i < @$a; $i++) { - my ($rm, $add) = highlight_pair($a->[$i], $b->[$i]); - $line_cb->($rm); - push @queue, $add; - } - $line_cb->(@queue); - } - - sub highlight_pair { - my @a = split_line(shift); - my @b = split_line(shift); - - # Find common prefix, taking care to skip any ansi - # color codes. - my $seen_plusminus; - my ($pa, $pb) = (0, 0); - while ($pa < @a && $pb < @b) { - if ($a[$pa] =~ /$COLOR/) { - $pa++; - } - elsif ($b[$pb] =~ /$COLOR/) { - $pb++; - } - elsif ($a[$pa] eq $b[$pb]) { - $pa++; - $pb++; - } - elsif (!$seen_plusminus && $a[$pa] eq '-' && $b[$pb] eq '+') { - $seen_plusminus = 1; - $pa++; - $pb++; - } - else { - last; - } - } - - # Find common suffix, ignoring colors. - my ($sa, $sb) = ($#a, $#b); - while ($sa >= $pa && $sb >= $pb) { - if ($a[$sa] =~ /$COLOR/) { - $sa--; - } - elsif ($b[$sb] =~ /$COLOR/) { - $sb--; - } - elsif ($a[$sa] eq $b[$sb]) { - $sa--; - $sb--; - } - else { - last; - } - } - - if (is_pair_interesting(\@a, $pa, $sa, \@b, $pb, $sb)) { - return highlight_line(\@a, $pa, $sa, \@OLD_HIGHLIGHT), - highlight_line(\@b, $pb, $sb, \@NEW_HIGHLIGHT); - } - else { - return join('', @a), - join('', @b); - } - } - - # we split either by $COLOR or by character. This has the side effect of - # leaving in graph cruft. It works because the graph cruft does not contain "-" - # or "+" - sub split_line { - local $_ = shift; - return utf8::decode($_) ? - map { utf8::encode($_); $_ } - map { /$COLOR/ ? $_ : (split //) } - split /($COLOR+)/ : - map { /$COLOR/ ? $_ : (split //) } - split /($COLOR+)/; - } - - sub highlight_line { - my ($line, $prefix, $suffix, $theme) = @_; - - my $start = join('', @{$line}[0..($prefix-1)]); - my $mid = join('', @{$line}[$prefix..$suffix]); - my $end = join('', @{$line}[($suffix+1)..$#$line]); - - # If we have a "normal" color specified, then take over the whole line. - # Otherwise, we try to just manipulate the highlighted bits. - if (defined $theme->[0]) { - s/$COLOR//g for ($start, $mid, $end); - chomp $end; - return join('', - $theme->[0], $start, $RESET, - $theme->[1], $mid, $RESET, - $theme->[0], $end, $RESET, - "\n" - ); - } else { - return join('', - $start, - $theme->[1], $mid, $theme->[2], - $end - ); - } - } - - # Pairs are interesting to highlight only if we are going to end up - # highlighting a subset (i.e., not the whole line). Otherwise, the highlighting - # is just useless noise. We can detect this by finding either a matching prefix - # or suffix (disregarding boring bits like whitespace and colorization). - sub is_pair_interesting { - my ($a, $pa, $sa, $b, $pb, $sb) = @_; - my $prefix_a = join('', @$a[0..($pa-1)]); - my $prefix_b = join('', @$b[0..($pb-1)]); - my $suffix_a = join('', @$a[($sa+1)..$#$a]); - my $suffix_b = join('', @$b[($sb+1)..$#$b]); - - return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ || - visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ || - $suffix_a !~ /^$BORING*$/ || - $suffix_b !~ /^$BORING*$/; - } -DIFFHIGHLIGHT - -s/^ //mg for values %fatpacked; - -my $class = 'FatPacked::'.(0+\%fatpacked); -no strict 'refs'; -*{"${class}::files"} = sub { keys %{$_[0]} }; - -if ($] < 5.008) { - *{"${class}::INC"} = sub { - if (my $fat = $_[0]{$_[1]}) { - my $pos = 0; - my $last = length $fat; - return (sub { - return 0 if $pos == $last; - my $next = (1 + index $fat, "\n", $pos) || $last; - $_ .= substr $fat, $pos, $next - $pos; - $pos = $next; - return 1; - }); - } - }; -} - -else { - *{"${class}::INC"} = sub { - if (my $fat = $_[0]{$_[1]}) { - open my $fh, '<', \$fat - or die "FatPacker error loading $_[1] (could be a perl installation issue?)"; - return $fh; - } - return; - }; -} - -unshift @INC, bless \%fatpacked, $class; - } # END OF FATPACK CODE - - -my $VERSION = "1.4.0"; - -################################################################################# - -use 5.010; # Require Perl 5.10 for 'state' variables -use File::Spec; # For catdir -use File::Basename; # For dirname -use Encode; # For handling UTF8 stuff -use Cwd qw(abs_path); # For realpath() -use lib dirname(abs_path(File::Spec->catdir($0))) . "/lib"; # Add the local lib/ to @INC -use DiffHighlight; - -use strict; -use warnings FATAL => 'all'; - -my $remove_file_add_header = 1; -my $remove_file_delete_header = 1; -my $clean_permission_changes = 1; -my $patch_mode = 0; -my $manually_color_lines = 0; # Usually git/hg colorizes the lines, but for raw patches we use this -my $change_hunk_indicators = git_config_boolean("diff-so-fancy.changeHunkIndicators","true"); -my $strip_leading_indicators = git_config_boolean("diff-so-fancy.stripLeadingSymbols","true"); -my $mark_empty_lines = git_config_boolean("diff-so-fancy.markEmptyLines","true"); -my $use_unicode_dash_for_ruler = git_config_boolean("diff-so-fancy.useUnicodeRuler","true"); -my $ruler_width = git_config("diff-so-fancy.rulerWidth", undef); -my $git_strip_prefix = git_config_boolean("diff.noprefix","false"); -my $has_stdin = has_stdin(); - -my $ansi_color_regex = qr/(\e\[([0-9]{1,3}(;[0-9]{1,3}){0,10})[mK])?/; -my $reset_color = color("reset"); -my $bold = color("bold"); -my $meta_color = ""; - -my ($file_1,$file_2); -my $args = argv(); # Hashref of all the ARGV stuff -my $last_file_seen = ""; -my $last_file_mode = ""; -my $i = 0; -my $in_hunk = 0; -my $columns_to_remove = 0; -my $is_mercurial = 0; -my $color_forced = 0; # Has the color been forced on/off - -# We try and be smart about whether we need to do line coloring, but -# this is an option to force it on/off -if ($args->{color_on}) { - $manually_color_lines = 1; - $color_forced = 1; -} elsif ($args->{color_off}) { - $manually_color_lines = 0; - $color_forced = 1; -} - -if ($args->{debug}) { - show_debug_info(); - exit(); -} - -# `git add --patch` requires our output to match the number of lines from the -# input. So, when patch mode is active, we print out empty lines to pad our -# output to match any lines we've consumed. -if ($args->{patch}) { - $patch_mode = 1; -} - -# We only process ARGV if we don't have STDIN -if (!$has_stdin) { - if ($args->{v} || $args->{version}) { - die(version()); - } elsif ($args->{'set-defaults'}) { - my $ok = set_defaults(); - } elsif ($args->{colors}) { - # We print this to STDOUT so we can redirect to bash to auto-set the colors - print get_default_colors(); - exit; - } elsif (!%$args || $args->{help} || $args->{h}) { - my $first = check_first_run(); - - if (!$first) { - die(usage()); - } - } else { - die("Missing input on STDIN\n"); - } -} else { - # Check to see if were using default settings - check_first_run(); - - my @lines; - local $DiffHighlight::line_cb = sub { - push(@lines,@_); - - my $last_line = $lines[-1]; - - # Buffer X lines before we try and output anything - # Also make sure we're sending enough data to d-s-f to do it's magic. - # Certain things require a look-ahead line or two to function so - # we make sure we don't break on those sections prematurely - if (@lines > 24 && ($last_line !~ /^${ansi_color_regex}(---|index|old mode|similarity index|rename (from|to))/)) { - do_dsf_stuff(\@lines); - @lines = (); - } - }; - - my $line_count = 0; - while (my $line = <STDIN>) { - # If the very first line of the diff doesn't start with ANSI color we're assuming - # it's a raw patch file, and we have to color the added/removed lines ourself - if (!$color_forced && $line_count == 0 && starts_with_ansi($line)) { - $manually_color_lines = 1; - } - - my $ok = DiffHighlight::handle_line($line); - $line_count++; - } - - DiffHighlight::flush(); - do_dsf_stuff(\@lines); -} - -################################################################################# - -sub do_dsf_stuff { - my $input = shift(); - - #print STDERR "START -------------------------------------------------\n"; - #print STDERR join("",@$input); - #print STDERR "END ---------------------------------------------------\n"; - - while (my $line = shift(@$input)) { - ###################################################### - # Pre-process the line before we do any other markup # - ###################################################### - - # If the first line of the input is a blank line, skip that - if ($i == 0 && $line =~ /^\s*$/) { - next; - } - - ###################### - # End pre-processing # - ###################### - - ####################################################################### - - #################################################################### - # Look for git index and replace it horizontal line (header later) # - #################################################################### - if ($line =~ /^${ansi_color_regex}index /) { - # Print the line color and then the actual line - $meta_color = $1 || get_config_color("meta"); - - # Get the next line without incrementing counter while loop - my $next = $input->[0] || ""; - my ($file_1,$file_2); - - # The line immediately after the "index" line should be the --- file line - # If it's not it's an empty file add/delete - if ($next !~ /^$ansi_color_regex(---|Binary files)/) { - - # We fake out the file names since it's a raw add/delete - if ($last_file_mode eq "add") { - $file_1 = "/dev/null"; - $file_2 = $last_file_seen; - } elsif ($last_file_mode eq "delete") { - $file_1 = $last_file_seen; - $file_2 = "/dev/null"; - } - } - - if ($file_1 && $file_2) { - print horizontal_rule($meta_color); - print $meta_color . file_change_string($file_1,$file_2) . "\n"; - print horizontal_rule($meta_color); - } - ######################### - # Look for the filename # - ######################### - # $4 $5 - } elsif ($line =~ /^${ansi_color_regex}diff (-r|--git|--cc) (.*?)(\e| b\/|$)/) { - - # Mercurial looks like: diff -r 82e55d328c8c hello.c - if ($4 eq "-r") { - $is_mercurial = 1; - $meta_color ||= get_config_color("meta"); - # Git looks like: diff --git a/diff-so-fancy b/diff-so-fancy - } else { - $last_file_seen = $5; - } - - $last_file_seen =~ s|^\w/||; # Remove a/ (and handle diff.mnemonicPrefix). - $in_hunk = 0; - if ($patch_mode) { - # we are consuming one line, and the debt must be paid - print "\n"; - } - ######################################## - # Find the first file: --- a/README.md # - ######################################## - } elsif (!$in_hunk && $line =~ /^$ansi_color_regex--- (\w\/)?(.+?)(\e|\t|$)/) { - $meta_color ||= get_config_color("meta"); - - if ($git_strip_prefix) { - my $file_dir = $4 || ""; - $file_1 = $file_dir . $5; - } else { - $file_1 = $5; - } - - # Find the second file on the next line: +++ b/README.md - my $next = shift(@$input); - $next =~ /^$ansi_color_regex\+\+\+ (\w\/)?(.+?)(\e|\t|$)/; - if ($1) { - print $1; # Print out whatever color we're using - } - if ($git_strip_prefix) { - my $file_dir = $4 || ""; - $file_2 = $file_dir . $5; - } else { - $file_2 = $5; - } - - if ($file_2 ne "/dev/null") { - $last_file_seen = $file_2; - } - - # Print out the top horizontal line of the header - print $reset_color; - print horizontal_rule($meta_color); - - # Mercurial coloring is slightly different so we need to hard reset colors - if ($is_mercurial) { - print $reset_color; - } - - print $meta_color; - print file_change_string($file_1,$file_2) . "\n"; - - # Print out the bottom horizontal line of the header - print horizontal_rule($meta_color); - ######################################## - # Check for "@@ -3,41 +3,63 @@" syntax # - ######################################## - } elsif (!$change_hunk_indicators && $line =~ /^${ansi_color_regex}(@@@* .+? @@@*)(.*)/) { - $in_hunk = 1; - - print $line; - } elsif ($change_hunk_indicators && $line =~ /^${ansi_color_regex}(@@@* .+? @@@*)(.*)/) { - $in_hunk = 1; - - my $hunk_header = $4; - my $remain = bleach_text($5); - - # The number of colums to remove (1 or 2) is based on how many commas in the hunk header - $columns_to_remove = (char_count(",",$hunk_header)) - 1; - # On single line removes there is NO comma in the hunk so we force one - if ($columns_to_remove <= 0) { - $columns_to_remove = 1; - } - - if ($1) { - print $1; # Print out whatever color we're using - } - - my ($orig_offset, $orig_count, $new_offset, $new_count) = parse_hunk_header($hunk_header); - #$last_file_seen = basename($last_file_seen); - - # Figure out the start line - my $start_line = start_line_calc($new_offset,$new_count); - - # Last function has it's own color - my $last_function_color = ""; - if ($remain) { - $last_function_color = get_config_color("last_function"); - } - - # Check to see if we have the color for the fragment from git - if ($5 =~ /\e\[\d/) { - #print "Has ANSI color for fragment\n"; - } else { - # We don't have the ANSI sequence so we shell out to get it - #print "No ANSI color for fragment\n"; - my $frag_color = get_config_color("fragment"); - print $frag_color; - } - - print "@ $last_file_seen:$start_line \@${bold}${last_function_color}${remain}${reset_color}\n"; - ################################### - # Remove any new file permissions # - ################################### - } elsif ($remove_file_add_header && $line =~ /^${ansi_color_regex}.*new file mode/) { - # Don't print the line (i.e. remove it from the output); - $last_file_mode = "add"; - if ($patch_mode) { - print "\n"; - } - ###################################### - # Remove any delete file permissions # - ###################################### - } elsif ($remove_file_delete_header && $line =~ /^${ansi_color_regex}deleted file mode/) { - # Don't print the line (i.e. remove it from the output); - $last_file_mode = "delete"; - if ($patch_mode) { - print "\n"; - } - ################################ - # Look for binary file changes # - ################################ - } elsif ($line =~ /^Binary files (\w\/)?(.+?) and (\w\/)?(.+?) differ/) { - my $change = file_change_string($2,$4); - print horizontal_rule($meta_color); - print "$meta_color$change (binary)\n"; - print horizontal_rule($meta_color); - ##################################################### - # Check if we're changing the permissions of a file # - ##################################################### - } elsif ($clean_permission_changes && $line =~ /^${ansi_color_regex}old mode (\d+)/) { - my ($old_mode) = $4; - my $next = shift(@$input); - - if ($1) { - print $1; # Print out whatever color we're using - } - - my ($new_mode) = $next =~ m/new mode (\d+)/; - - if ($patch_mode) { - print "\n"; - } - print "$last_file_seen changed file mode from $old_mode to $new_mode\n"; - - ############### - # File rename # - ############### - } elsif ($line =~ /^${ansi_color_regex}similarity index (\d+)%/) { - my $simil = $4; - - # If it's a move with content change we ignore this and the next two lines - if ($simil != 100) { - shift(@$input); - shift(@$input); - next; - } - - my $next = shift(@$input); - my ($file1) = $next =~ /rename from (.+)/; - - $next = shift(@$input); - my ($file2) = $next =~ /rename to (.+)/; - - if ($file1 && $file2) { - # We may not have extracted this yet, so we pull from the config if not - $meta_color ||= get_config_color("meta"); - - my $change = file_change_string($file1,$file2); - - print horizontal_rule($meta_color); - print $meta_color . $change . "\n"; - print horizontal_rule($meta_color); - } - - $i += 3; # We've consumed three lines - next; - ##################################### - # Just a regular line, print it out # - ##################################### - } else { - # Mark empty line with a red/green box indicating addition/removal - if ($mark_empty_lines) { - $line = mark_empty_line($line); - } - - # Remove the correct number of leading " " or "+" or "-" - if ($strip_leading_indicators) { - $line = strip_leading_indicators($line,$columns_to_remove); - } - print $line; - } - - $i++; - } -} - -###################################################################################################### -# End regular code, begin functions -###################################################################################################### - -# Courtesy of github.com/git/git/blob/ab5d01a/git-add--interactive.perl#L798-L805 -sub parse_hunk_header { - my ($line) = @_; - my ($o_ofs, $o_cnt, $n_ofs, $n_cnt) = $line =~ /^\@\@+(?: -(\d+)(?:,(\d+))?)+ \+(\d+)(?:,(\d+))? \@\@+/; - $o_cnt = 1 unless defined $o_cnt; - $n_cnt = 1 unless defined $n_cnt; - return ($o_ofs, $o_cnt, $n_ofs, $n_cnt); -} - -# Mark the first char of an empty line -sub mark_empty_line { - my $line = shift(); - - my $reset_color = "\e\\[0?m"; - my $reset_escape = "\e\[m"; - my $invert_color = "\e\[7m"; - my $add_color = $DiffHighlight::NEW_HIGHLIGHT[1]; - my $del_color = $DiffHighlight::OLD_HIGHLIGHT[1]; - - # This captures lines that do not have any ANSI in them (raw vanilla diff) - if ($line eq "+\n") { - $line = $invert_color . $add_color . " " . color('reset') . "\n"; - # This captures lines that do not have any ANSI in them (raw vanilla diff) - } elsif ($line eq "-\n") { - $line = $invert_color . $del_color . " " . color('reset') . "\n"; - # This handles everything else - } else { - $line =~ s/^($ansi_color_regex)[+-]$reset_color\s*$/$invert_color$1 $reset_escape\n/; - } - - return $line; -} - -# String to boolean -sub boolean { - my $str = shift(); - $str = trim($str); - - if ($str eq "" || $str =~ /^(no|false|0)$/i) { - return 0; - } else { - return 1; - } -} - -# Memoize getting the git config -{ - my $static_config; - - sub git_config_raw { - if ($static_config) { - # If we already have the config return that - return $static_config; - } - - my $cmd = "git config --list"; - my @out = `$cmd`; - - $static_config = \@out; - - return \@out; - } -} - -# Fetch a textual item from the git config -sub git_config { - my $search_key = lc($_[0] || ""); - my $default_value = lc($_[1] || ""); - - my $out = git_config_raw(); - - # If we're in a unit test, use the default (don't read the users config) - if (in_unit_test()) { - return $default_value; - } - - my $raw = {}; - foreach my $line (@$out) { - if ($line =~ /=/) { - my ($key,$value) = split("=",$line,2); - $value =~ s/\s+$//; - $raw->{$key} = $value; - } - } - - # If we're given a search key return that, else return the hash - if ($search_key) { - return $raw->{$search_key} || $default_value; - } else { - return $raw; - } -} - -# Fetch a boolean item from the git config -sub git_config_boolean { - my $search_key = lc($_[0] || ""); - my $default_value = lc($_[1] || 0); # Default to false - - # If we're in a unit test, use the default (don't read the users config) - if (in_unit_test()) { - return boolean($default_value); - } - - my $result = git_config($search_key,$default_value); - my $ret = boolean($result); - - return $ret; -} - -# Check if we're inside of BATS -sub in_unit_test { - if ($ENV{BATS_CWD}) { - return 1; - } else { - return 0; - } -} - -sub get_less_charset { - my @less_char_vars = ("LESSCHARSET", "LESSCHARDEF", "LC_ALL", "LC_CTYPE", "LANG"); - foreach my $key (@less_char_vars) { - my $val = $ENV{$key}; - - if (defined $val) { - return ($key, $val); - } - } - - return (); -} - -sub should_print_unicode { - if (-t STDOUT) { - # Always print unicode chars if we're not piping stuff, e.g. to less(1) - return 1; - } - - # Otherwise, assume we're piping to less(1) - my ($less_env_var, $less_charset) = get_less_charset(); - $less_charset //= ""; - if ($less_charset =~ /utf-?8/i) { - return 1; - } - - return 0; -} - -# Try and be smart about what line the diff hunk starts on -sub start_line_calc { - my ($line_num,$diff_context) = @_; - my $ret; - - if ($line_num == 0 && $diff_context == 0) { - return 1; - } - - # Git defaults to three lines of context - my $default_context_lines = 3; - # Three lines on either side, and the line itself = 7 - my $expected_context = ($default_context_lines * 2 + 1); - - # The first three lines - if ($line_num == 1 && $diff_context < $expected_context) { - $ret = $diff_context - $default_context_lines; - } else { - $ret = $line_num + $default_context_lines; - } - - if ($ret < 1) { - $ret = 1; - } - - return $ret; -} - -# Remove + or - at the beginning of the lines -sub strip_leading_indicators { - my $line = shift(); # Array passed in by reference - my $columns_to_remove = shift(); # Don't remove any lines by default - - if ($columns_to_remove == 0) { - return $line; # Nothing to do - } - - $line =~ s/^(${ansi_color_regex})([ +-]){${columns_to_remove}}/$1/; - - if ($manually_color_lines) { - if (defined($5) && $5 eq "+") { - my $add_line_color = get_config_color("add_line"); - $line = $add_line_color . insert_reset_at_line_end($line); - } elsif (defined($5) && $5 eq "-") { - my $remove_line_color = get_config_color("remove_line"); - $line = $remove_line_color . insert_reset_at_line_end($line); - } - } - - return $line; -} - -# Insert the color reset code at end of line, but before any newlines -sub insert_reset_at_line_end { - my $line = shift(); - $line =~ s/^(.*)([\n\r]+)?$/${1}${reset_color}${2}/; - return $line; -} - -# Count the number of a given char in a string -sub char_count { - my ($needle,$str) = @_; - my $len = length($str); - my $ret = 0; - - for (my $i = 0; $i < $len; $i++) { - my $found = substr($str,$i,1); - - if ($needle eq $found) { $ret++; } - } - - return $ret; -} - -# Remove all ANSI codes from a string -sub bleach_text { - my $str = shift(); - $str =~ s/\e\[\d*(;\d+)*m//mg; - - return $str; -} - -# Remove all trailing and leading spaces -sub trim { - my $s = shift(); - if (!$s) { return ""; } - $s =~ s/^\s*|\s*$//g; - - return $s; -} - -# Print a line of em-dash or line-drawing chars the full width of the screen -sub horizontal_rule { - my $color = $_[0] || ""; - my $width = get_terminal_width(); - - # em-dash http://www.fileformat.info/info/unicode/char/2014/index.htm - #my $dash = "\x{2014}"; - # BOX DRAWINGS LIGHT HORIZONTAL http://www.fileformat.info/info/unicode/char/2500/index.htm - my $dash; - if ($use_unicode_dash_for_ruler && should_print_unicode()) { - $dash = Encode::encode('UTF-8', "\x{2500}"); - } else { - $dash = "-"; - } - - # Draw the line - my $ret = $color . ($dash x $width) . "$reset_color\n"; - - return $ret; -} - -sub file_change_string { - my $file_1 = shift(); - my $file_2 = shift(); - - # If they're the same it's a modify - if ($file_1 eq $file_2) { - return "modified: $file_1"; - # If the first is /dev/null it's a new file - } elsif ($file_1 eq "/dev/null") { - my $add_color = $DiffHighlight::NEW_HIGHLIGHT[1]; - return "added: $add_color$file_2$reset_color"; - # If the second is /dev/null it's a deletion - } elsif ($file_2 eq "/dev/null") { - my $del_color = $DiffHighlight::OLD_HIGHLIGHT[1]; - return "deleted: $del_color$file_1$reset_color"; - # If the files aren't the same it's a rename - } elsif ($file_1 ne $file_2) { - my ($old, $new) = DiffHighlight::highlight_pair($file_1,$file_2,{only_diff => 1}); - $old = trim($old); - $new = trim($new); - - # highlight_pair resets the colors, but we want it to be the meta color - $old =~ s/(\e0?\[m)/$1$meta_color/g; - $new =~ s/(\e0?\[m)/$1$meta_color/g; - - return "renamed: $old to $new"; - # Something we haven't thought of yet - } else { - return "$file_1 -> $file_2"; - } -} - -# Check to see if STDIN is connected to an interactive terminal -sub has_stdin { - my $i = -t STDIN; - my $ret = int(!$i); - - return $ret; -} - -# We use this instead of Getopt::Long because it's faster and we're not parsing any -# crazy arguments -# Borrowed from: https://www.perturb.org/display/1153_Perl_Quick_extract_variables_from_ARGV.html -sub argv { - my $ret = {}; - - for (my $i = 0; $i < scalar(@ARGV); $i++) { - - # If the item starts with "-" it's a key - if ((my ($key) = $ARGV[$i] =~ /^--?([a-zA-Z_-]*\w)$/) && ($ARGV[$i] !~ /^-\w\w/)) { - # If the next item does not start with "--" it's the value for this item - if (defined($ARGV[$i + 1]) && ($ARGV[$i + 1] !~ /^--?\D/)) { - $ret->{$key} = $ARGV[$i + 1]; - # Bareword like --verbose with no options - } else { - $ret->{$key}++; - } - } - } - - # We're looking for a certain item - if ($_[0]) { return $ret->{$_[0]}; } - - return $ret; -} - -# Output the command line usage for d-s-f -sub usage { - my $out = color("white_bold") . version() . color("reset") . "\n"; - - $out .= "Usage: - -git diff --color | diff-so-fancy # Use d-s-f on one diff -cat diff.txt | diff-so-fancy # Use d-s-f on a diff/patch file -diff -u one.txt two.txt | diff-so-fancy # Use d-s-f on unified diff output - -diff-so-fancy --colors # View the commands to set the recommended colors -diff-so-fancy --set-defaults # Configure git-diff to use diff-so-fancy and suggested colors -diff-so-fancy --patch # Use diff-so-fancy in patch mode (interoperable with `git add --patch`) - -# Configure git to use d-s-f for *all* diff operations -git config --global core.pager \"diff-so-fancy | less --tabs=4 -RFX\" - -# Configure git to use d-s-f for `git add --patch` -git config --global interactive.diffFilter \"diff-so-fancy --patch\"\n"; - - return $out; -} - -sub get_default_colors { - my $out = "# Recommended default colors for diff-so-fancy\n"; - $out .= "# --------------------------------------------\n"; - $out .= 'git config --global color.ui true - -git config --global color.diff-highlight.oldNormal "red bold" -git config --global color.diff-highlight.oldHighlight "red bold 52" -git config --global color.diff-highlight.newNormal "green bold" -git config --global color.diff-highlight.newHighlight "green bold 22" - -git config --global color.diff.meta "yellow" -git config --global color.diff.frag "magenta bold" -git config --global color.diff.commit "yellow bold" -git config --global color.diff.old "red bold" -git config --global color.diff.new "green bold" -git config --global color.diff.whitespace "red reverse" -'; - - return $out; -} - -# Output the current version string -sub version { - my $ret = "Diff-so-fancy: https://github.com/so-fancy/diff-so-fancy\n"; - $ret .= "Version : $VERSION\n"; - - return $ret; -} - -sub is_windows { - if ($^O eq 'MSWin32' or $^O eq 'dos' or $^O eq 'os2' or $^O eq 'cygwin' or $^O eq 'msys') { - return 1; - } else { - return 0; - } -} - -# Return value is whether this is the first time they've run d-s-f -sub check_first_run { - my $ret = 0; - - # If first-run is not set, or it's set to "true" - my $first_run = git_config_boolean('diff-so-fancy.first-run'); - # See if they're previously set SOME diff-highlight colors - my $has_dh_colors = git_config_boolean('color.diff-highlight.oldnormal') || git_config_boolean('color.diff-highlight.newnormal'); - - #$first_run = 1; $has_dh_colors = 0; - - if (!$first_run || $has_dh_colors) { - return 0; - } else { - print "This appears to be the first time you've run diff-so-fancy, please note\n"; - print "that the default git colors are not ideal. Diff-so-fancy recommends the\n"; - print "following colors.\n\n"; - - print get_default_colors(); - - # Set the first run flag to false - my $cmd = 'git config --global diff-so-fancy.first-run false'; - system($cmd); - - exit; - } - - return 1; -} - -sub set_defaults { - my $color_config = get_default_colors(); - my $git_config = 'git config --global core.pager "diff-so-fancy | less --tabs=4 -RFX"'; - my $first_cmd = 'git config --global diff-so-fancy.first-run false'; - - my @cmds = split(/\n/,$color_config); - push(@cmds,$git_config); - push(@cmds,$first_cmd); - - # Remove all comments from the commands - foreach my $x (@cmds) { - $x =~ s/#.*//g; - } - - # Remove any empty commands - @cmds = grep($_,@cmds); - - foreach my $cmd (@cmds) { - system($cmd); - my $exit = ($? >> 8); - - if ($exit != 0) { - die("Error running: '$cmd' (error #18941)\n"); - } - } - - return 1; -} - -# Borrowed from: https://www.perturb.org/display/1167_Perl_ANSI_colors.html -# String format: '115', '165_bold', '10_on_140', 'reset', 'on_173', 'red', 'white_on_blue' -sub color { - my $str = shift(); - - # No string sent in, so we just reset - if (!length($str) || $str eq 'reset') { return "\e[0m"; } - - # Some predefined colors - my %color_map = qw(red 160 blue 21 green 34 yellow 226 orange 214 purple 93 white 15 black 0); - $str =~ s|([A-Za-z]+)|$color_map{$1} // $1|eg; - - # Get foreground/background and any commands - my ($fc,$cmd) = $str =~ /(\d+)?_?(\w+)?/g; - my ($bc) = $str =~ /on_?(\d+)/g; - - # Some predefined commands - my %cmd_map = qw(bold 1 italic 3 underline 4 blink 5 inverse 7); - my $cmd_num = $cmd_map{$cmd // 0}; - - my $ret = ''; - if ($cmd_num) { $ret .= "\e[${cmd_num}m"; } - if (defined($fc)) { $ret .= "\e[38;5;${fc}m"; } - if (defined($bc)) { $ret .= "\e[48;5;${bc}m"; } - - return $ret; -} - -# Get colors used for various output sections (memoized) -{ - my $static_config; - - sub get_config_color { - my $str = shift(); - - my $ret = ""; - if ($static_config->{$str}) { - return $static_config->{$str}; - } - - #print color(15) . "Shelling out for color: '$str'\n" . color('reset'); - - if ($str eq "meta") { - # Default ANSI yellow - $ret = DiffHighlight::color_config('color.diff.meta', color(11)); - } elsif ($str eq "reset") { - $ret = color("reset"); - } elsif ($str eq "add_line") { - # Default ANSI green - $ret = DiffHighlight::color_config('color.diff.new', color('bold') . color(2)); - } elsif ($str eq "remove_line") { - # Default ANSI red - $ret = DiffHighlight::color_config('color.diff.old', color('bold') . color(1)); - } elsif ($str eq "fragment") { - $ret = DiffHighlight::color_config('color.diff.frag', color('13_bold')); - } elsif ($str eq "last_function") { - $ret = DiffHighlight::color_config('color.diff.func', color('bold') . color(146)); - } - - # Cache (memoize) the entry for later - $static_config->{$str} = $ret; - - return $ret; - } -} - -sub starts_with_ansi { - my $str = shift(); - - if ($str =~ /^$ansi_color_regex/) { - return 1; - } else { - return 0; - } -} - -sub get_terminal_width { - # Make width static so we only calculate it once - state $width; - - if ($width) { - return $width; - } - - # If there is a ruler width in the config we use that - if ($ruler_width) { - $width = $ruler_width; - # Otherwise we check the terminal width using tput - } else { - my $tput = `tput cols`; - - if ($tput) { - $width = int($tput); - - if (is_windows()) { - $width--; - } - } else { - print color('orange') . "Warning: `tput cols` did not return numeric input" . color('reset') . "\n"; - $width = 80; - } - } - - return $width; -} - -sub show_debug_info { - my @less = get_less_charset(); - my $git_ver = trim(`git --version`); - $git_ver =~ s/[^\d.]//g; - - print "Diff-so-fancy : v$VERSION\n"; - print "Git : v$git_ver\n"; - print "Perl : $^V\n"; - print "\n"; - - print "Terminal width : " . get_terminal_width() . "\n"; - print "Terminal \$LANG : " . $ENV{LANG} . "\n"; - print "\n"; - print "Supports Unicode: " . yes_no(should_print_unicode()) . "\n"; - print "Unicode Ruler : " . yes_no($use_unicode_dash_for_ruler) . "\n"; - print "\n"; - print "Less Charset Var: " . ($less[0] // "") . "\n"; - print "Less Charset : " . ($less[1] // "") . "\n"; - print "\n"; - print "Is Windows : " . yes_no(is_windows()) . "\n"; - print "Operating System: $^O\n"; -} - -sub yes_no { - my $val = shift(); - - if ($val) { - return "Yes"; - } else { - return "No"; - } -} - -# vim: tabstop=4 shiftwidth=4 noexpandtab autoindent softtabstop=4 @@ -0,0 +1,144 @@ +#!/usr/bin/env python3 +""" +Script add PIT mutation plugin to maven files and run mutations. +""" +import argparse +import os +import os.path +import shutil +import subprocess +import sys +import xml.etree.ElementTree as ET + +PIT_GROUP_ID = 'org.pitest' +PIT_ARTIFACT_ID = 'pitest-maven' +PIT_VERSION = '1.14.2' +PIT_JUNIT5_ARTIFACT_ID = 'pitest-junit5-plugin' +PIT_JUNIT5_VERSION = '1.2.0' +NAMESPACES = {'': 'http://maven.apache.org/POM/4.0.0'} +for prefix, url in NAMESPACES.items(): + ET.register_namespace(prefix, url) + +MUTATORS = [ + 'STRONGER' +] +OPEN_COMMAND = 'x-www-browser' # or xdg-open + + +def create_args(): + parser = argparse.ArgumentParser() + parser.add_argument('-pl', '--projects') + parser.add_argument('-pn', '--project-name') + parser.add_argument('-am', '--also-make', action='store_true') + parser.add_argument('-q', '--quiet', action='store_true') + parser.add_argument('globs', nargs='+') + return parser + + +def get_pom_files(): + for root, dirs, files in os.walk('.'): + for file in files: + if file == 'pom.xml': + yield os.path.join(root, file) + + +def make_file_backup(file): + dst = '%s.bak.%d' % (file, os.getpid()) + shutil.copyfile(file, dst) + return file, dst + + +def update_pom(file, project, globs): + tree = ET.parse(file) + root = tree.getroot() + + artifact_id = root.find('./artifactId', NAMESPACES).text + + build = root.find('./build', NAMESPACES) + if build is None: + build = ET.SubElement(root, 'build') + plugins = build.find('./plugins', NAMESPACES) + if plugins is None: + plugins = ET.SubElement(build, 'plugins') + + plugin = ET.SubElement(plugins, 'plugin') + ET.SubElement(plugin, 'groupId').text = PIT_GROUP_ID + ET.SubElement(plugin, 'artifactId').text = PIT_ARTIFACT_ID + ET.SubElement(plugin, 'version').text = PIT_VERSION + + dependencies = ET.SubElement(plugin, 'dependencies') + dependency = ET.SubElement(dependencies, 'dependency') + ET.SubElement(dependency, 'groupId').text = PIT_GROUP_ID + ET.SubElement(dependency, 'artifactId').text = PIT_JUNIT5_ARTIFACT_ID + ET.SubElement(dependency, 'version').text = PIT_JUNIT5_VERSION + + configuration = ET.SubElement(plugin, 'configuration') + + if artifact_id == project or project is None: + ET.SubElement(configuration, 'skip').text = 'False' + target_classes = ET.SubElement(configuration, 'targetClasses') + target_tests = ET.SubElement(configuration, 'targetTests') + for glob in globs: + ET.SubElement(target_classes, 'param').text = glob + ET.SubElement(target_tests, 'param').text = glob + mutators = ET.SubElement(configuration, 'mutators') + for mutator in MUTATORS: + ET.SubElement(mutators, 'mutator').text = mutator + formats = ET.SubElement(configuration, 'outputFormats') + ET.SubElement(formats, 'outputFormat').text = 'HTML' + ET.SubElement(formats, 'outputFormat').text = 'XML' + else: + ET.SubElement(configuration, 'skip').text = 'True' + + tree.write(file) + + +def run_mutation_coverage(args): + command = ['mvn', '--batch-mode', 'test-compile', 'org.pitest:pitest-maven:mutationCoverage'] + if args.also_make: + command.append('--also-make') + if args.projects: + command.append('--projects') + command.append(args.projects) + if args.quiet: + command.append('--quiet') + subprocess.call(' '.join(command), shell=True, stdout=sys.stdout, stderr=sys.stderr) + + +def print_details(filename): + subprocess.call(['pandoc', '--to', 'plain', filename], stdout=sys.stdout, stderr=sys.stderr) + + +def open_result(project): + target = os.path.join(project, 'target', 'pit-reports') + dirs = os.listdir(target) + if dirs: + last_dir = sorted(dirs)[-1] + index_file = os.path.join(target, last_dir, 'index.html') + if os.path.isfile(index_file): + print_details(index_file) + print('Report:', os.path.abspath(index_file)) + subprocess.call([OPEN_COMMAND, os.path.abspath(index_file)]) + + +def update_pom_files(args): + backup_files = [] + try: + for file in get_pom_files(): + backup_files.append(make_file_backup(file)) + update_pom(file, args.project_name or args.projects, args.globs) + + run_mutation_coverage(args) + open_result(args.projects) + finally: + for orig, backup in backup_files: + shutil.move(backup, orig) + + +def main(): + args = create_args().parse_args() + update_pom_files(args) + + +if __name__ == '__main__': + main() diff --git a/through-vpn.sh b/through-vpn.sh index 7e9e1ee..3d71404 100755 --- a/through-vpn.sh +++ b/through-vpn.sh @@ -8,4 +8,6 @@ if [ $# -eq 0 ] ; then exit 1 fi -ssh riga "/ip firewall address-list add address=$1 list=through-vpn" +comment=$(date +%F) + +ssh riga "/ip firewall address-list add address=$1 list=through-vpn comment=\"$comment\"" |
