-
-
Save sunyi00/1bd3dff94a9167f44f75d44e0c774d1f to your computer and use it in GitHub Desktop.
Format python source codes with autopep8 on only changed lines
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
| #!/bin/sh | |
| # Format python source codes with autopep8 on changed lines. | |
| # | |
| # Usage: | |
| # format all uncommitted lines: | |
| # > p8ln | |
| # | |
| # format file: | |
| # > p8ln a.py b.py | |
| # | |
| # --- | |
| # # Explaination: | |
| # | |
| # # show all changed file names: | |
| # git diff --name-only --relative HEAD | |
| # | |
| # And a helper script `git-changed-ln` outputs changed line numbers, | |
| # by diff work-tree(unstaged) with HEAD, | |
| # or by diff index(staged or cached) with HEAD. | |
| #include 'shlib.sh' begin | |
| #!/bin/sh | |
| shlib_init_colors() | |
| { | |
| Black="$( tput setaf 0)" | |
| BlackBG="$( tput setab 0)" | |
| DarkGrey="$( tput bold; tput setaf 0)" | |
| LightGrey="$( tput setaf 7)" | |
| LightGreyBG="$( tput setab 7)" | |
| White="$( tput bold; tput setaf 7)" | |
| Red="$( tput setaf 1)" | |
| RedBG="$( tput setab 1)" | |
| LightRed="$( tput bold; tput setaf 1)" | |
| Green="$( tput setaf 2)" | |
| GreenBG="$( tput setab 2)" | |
| LightGreen="$( tput bold; tput setaf 2)" | |
| Brown="$( tput setaf 3)" | |
| BrownBG="$( tput setab 3)" | |
| Yellow="$( tput bold; tput setaf 3)" | |
| Blue="$( tput setaf 4)" | |
| BlueBG="$( tput setab 4)" | |
| LightBlue="$( tput bold; tput setaf 4)" | |
| Purple="$( tput setaf 5)" | |
| PurpleBG="$( tput setab 5)" | |
| Pink="$( tput bold; tput setaf 5)" | |
| Cyan="$( tput setaf 6)" | |
| CyanBG="$( tput setab 6)" | |
| LightCyan="$( tput bold; tput setaf 6)" | |
| NC="$( tput sgr0)" # No Color | |
| } | |
| screen_width() | |
| { | |
| local chr="${1--}" | |
| chr="${chr:0:1}" | |
| local width=$(tput cols 2||echo 80) | |
| width="${COLUMNS:-$width}" | |
| echo $width | |
| } | |
| hr() | |
| { | |
| # generate a full screen width horizontal ruler | |
| local width=$(screen_width) | |
| printf -vl "%${width}s\n" && echo ${l// /$chr}; | |
| } | |
| remove_color() | |
| { | |
| # remove color control chars from stdin or first argument | |
| local sed=gsed | |
| which -s $sed || sed=sed | |
| local s="$1" | |
| if [ -z "$s" ]; then | |
| $sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | |
| else | |
| echo "$s" | remove_color | |
| fi | |
| } | |
| text_hr() | |
| { | |
| # generate a full screen width sperator line with text. | |
| # text_hr "-" "a title" | |
| # > a title ----------------------------------------- | |
| # | |
| # variable LR=l|m|r controls alignment | |
| local chr="$1" | |
| shift | |
| local bb="$(echo "$@" | remove_color)" | |
| local text_len=${#bb} | |
| local width=$(screen_width) | |
| let width=width-text_len | |
| local lr=${LR-m} | |
| case $lr in | |
| m) | |
| let left=width/2 | |
| let right=width-left | |
| echo "$(printf -vl "%${left}s\n" && echo ${l// /$chr})$@$(printf -vl "%${right}s\n" && echo ${l// /$chr})" | |
| ;; | |
| r) | |
| echo "$(printf -vl "%${width}s\n" && echo ${l// /$chr})$@" | |
| ;; | |
| *) | |
| # l by default | |
| echo "$@$(printf -vl "%${width}s\n" && echo ${l// /$chr})" | |
| ;; | |
| esac | |
| } | |
| SHLIB_LOG_VERBOSE=1 | |
| SHLIB_LOG_FORMAT='[$(date +"%Y-%m-%d %H:%M:%S")] $level $title $mes' | |
| die() | |
| { | |
| err "$@" >&2 | |
| exit 1 | |
| } | |
| die_empty() | |
| { | |
| if test -z "$1" | |
| then | |
| shift | |
| die empty: "$@" | |
| fi | |
| } | |
| set_verbose() | |
| { | |
| SHLIB_LOG_VERBOSE=${1-1} | |
| } | |
| log() | |
| { | |
| local color="$1" | |
| local title="$2" | |
| local level="$_LOG_LEVEL" | |
| shift | |
| shift | |
| local mes="$@" | |
| local NC="$(tput sgr0)" | |
| if [ -t 1 ]; then | |
| title="${color}${title}${NC}" | |
| level="${color}${level}${NC}" | |
| fi | |
| eval "echo \"$SHLIB_LOG_FORMAT\"" | |
| } | |
| dd() | |
| { | |
| debug "$@" | |
| } | |
| debug() | |
| { | |
| if [ ".$SHLIB_LOG_VERBOSE" = ".1" ]; then | |
| local LightCyan="$(tput bold ; tput setaf 6)" | |
| _LOG_LEVEL=DEBUG log "$LightCyan" "$@" | |
| fi | |
| } | |
| info() | |
| { | |
| local Brown="$(tput setaf 3)" | |
| _LOG_LEVEL=" INFO" log "$Brown" "$@" | |
| } | |
| ok() { | |
| local Green="$(tput setaf 2)" | |
| _LOG_LEVEL=" OK" log "${Green}" "$@" | |
| } | |
| err() { | |
| local Red="$(tput setaf 1)" | |
| _LOG_LEVEL="ERROR" log "${Red}" "$@" | |
| } | |
| git_hash() | |
| { | |
| git rev-parse $1 \ | |
| || die "'git_hash $@'" | |
| } | |
| git_is_merge() | |
| { | |
| test $(git cat-file -p "$1" | grep "^parent " | wc -l) -gt 1 | |
| } | |
| git_parents() | |
| { | |
| git rev-list --parents -n 1 ${1-HEAD} | { read self parents; echo $parents; } | |
| } | |
| git_rev_list() | |
| { | |
| # --parents | |
| # print parent in this form: | |
| # <commit> <parent-1> <parent-2> .. | |
| git rev-list \ | |
| --reverse \ | |
| --topo-order \ | |
| --default HEAD \ | |
| --simplify-merges \ | |
| "$@" \ | |
| || die "'git rev-list $@'" | |
| } | |
| git_tree_hash() | |
| { | |
| git rev-parse "$1^{tree}" | |
| } | |
| git_ver() | |
| { | |
| local git_version=$(git --version | awk '{print $NF}') | |
| local git_version_1=${git_version%%.*} | |
| local git_version_2=${git_version#*.} | |
| git_version_2=${git_version_2%%.*} | |
| printf "%03d%03d" $git_version_1 $git_version_2 | |
| } | |
| git_working_root() | |
| { | |
| git rev-parse --show-toplevel | |
| } | |
| git_branch_default_remote() | |
| { | |
| local branchname=$1 | |
| git config --get branch.${branchname}.remote | |
| } | |
| git_branch_default_upstream_ref() | |
| { | |
| local branchname=$1 | |
| git config --get branch.${branchname}.merge | |
| } | |
| git_branch_default_upstream() | |
| { | |
| git_branch_default_upstream_ref "$@" | sed 's/^refs\/heads\///' | |
| } | |
| git_head_branch() | |
| { | |
| git symbolic-ref --short HEAD | |
| } | |
| git_commit_copy() | |
| { | |
| # We're going to set some environment vars here, so | |
| # do it in a subshell to get rid of them safely later | |
| dd copy_commit "{$1}" "{$2}" "{$3}" | |
| git log -1 --pretty=format:'%an%n%ae%n%ad%n%cn%n%ce%n%cd%n%s%n%n%b' "$1" | | |
| ( | |
| read GIT_AUTHOR_NAME | |
| read GIT_AUTHOR_EMAIL | |
| read GIT_AUTHOR_DATE | |
| read GIT_COMMITTER_NAME | |
| read GIT_COMMITTER_EMAIL | |
| read GIT_COMMITTER_DATE | |
| export GIT_AUTHOR_NAME \ | |
| GIT_AUTHOR_EMAIL \ | |
| GIT_AUTHOR_DATE \ | |
| GIT_COMMITTER_NAME \ | |
| GIT_COMMITTER_EMAIL \ | |
| GIT_COMMITTER_DATE | |
| # (echo -n "$annotate"; cat ) | | |
| git commit-tree "$2" $3 # reads the rest of stdin | |
| ) || die "Can't copy commit $1" | |
| } | |
| git_objetct_type() | |
| { | |
| # $0 ref|hash | |
| # output "commit", "tree" etc | |
| git cat-file -t "$@" 2>/dev/null | |
| } | |
| git_copy_commit() | |
| { | |
| git_commit_copy "$@" | |
| } | |
| git_diff_ln_new() | |
| { | |
| # output changed line number of a file: <from> <end>; inclusive: | |
| # 27 28 | |
| # 307 309 | |
| # 350 350 | |
| # | |
| # Usage: | |
| # | |
| # diff working tree with HEAD: | |
| # git_diff_ln_new HEAD -- <fn> | |
| # | |
| # diff working tree with staged: | |
| # git_diff_ln_new -- <fn> | |
| # | |
| # diff staged(cached) with HEAD: | |
| # git_diff_ln_new --cached -- <fn> | |
| # | |
| # in git-diff output: | |
| # for add lines: | |
| # @@ -53 +72,8 | |
| # | |
| # for remove lines: | |
| # @@ -155 +179,0 | |
| git diff -U0 "$@" \ | |
| | grep '^@@' \ | |
| | awk '{ | |
| # @@ -155 +179,0 | |
| # $1 $2 $3 | |
| l = $3 | |
| gsub("^+", "", l) | |
| # add default offset: ",1" | |
| split(l",1", x, ",") | |
| # inclusive line range: | |
| x[2] = x[1] + x[2] - 1 | |
| # line remove format: @@ -155, +179,0 | |
| # do need to output line range for removed. | |
| if (x[2] >= x[1]) { | |
| print x[1] " " x[2] | |
| } | |
| }' | |
| } | |
| os_detect() | |
| { | |
| local os | |
| case $(uname -s) in | |
| Linux) | |
| os=linux ;; | |
| *[bB][sS][dD]) | |
| os=bsd ;; | |
| Darwin) | |
| os=mac ;; | |
| *) | |
| os=unix ;; | |
| esac | |
| echo $os | |
| } | |
| mac_ac_power_connection() | |
| { | |
| # Connected: (Yes|No) | |
| system_profiler SPPowerDataType \ | |
| | sed '1,/^ *AC Charger Information:/d' \ | |
| | grep Connected: | |
| } | |
| mac_power() | |
| { | |
| # $0 is-battery exit code 0 if using battery. | |
| # $0 is-ac-power exit code 0 if using ac power. | |
| local cmd="$1" | |
| local os=$(os_detect) | |
| if [ "$os" != "mac" ]; then | |
| err "not mac but: $os" | |
| return 1 | |
| fi | |
| case $cmd in | |
| is-battery) | |
| mac_ac_power_connection | grep -q No | |
| ;; | |
| is-ac-power) | |
| mac_ac_power_connection | grep -q Yes | |
| ;; | |
| *) | |
| err "invalid cmd: $cmd" | |
| return 1 | |
| ;; | |
| esac | |
| } | |
| fn_match() | |
| { | |
| # $0 a.txt *.txt | |
| case "$1" in | |
| $2) | |
| return 0 | |
| ;; | |
| esac | |
| return 1 | |
| } | |
| #include 'shlib.sh' end | |
| autopep8_options='--max-line-length 120' | |
| cmd_reverse=tac | |
| which -s $cmd_reverse || cmd_reverse="tail -r" | |
| { | |
| if [ "$#" -gt 0 ]; then | |
| # fns specified by command line args | |
| while [ "$#" -gt 0 ]; do | |
| echo "$1" | |
| shift | |
| done | |
| else | |
| # find fns by diff | |
| # get changed fn | |
| git diff --name-only --relative HEAD | |
| fi | |
| } | while read fn; do | |
| # reverse order, autopep8 may add or remove lines | |
| echo formating "$fn" ... | |
| git_diff_ln_new HEAD -- "$fn" | |
| git_diff_ln_new HEAD -- "$fn" \ | |
| | $cmd_reverse \ | |
| | while read f t; do | |
| autopep8 $autopep8_options -i --line-range $f $t "$fn" | |
| done | |
| done | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment