|
| 1 | +#!/bin/sh |
| 2 | +# |
| 3 | +# Copyright (c) 2016, Thurston Stone |
| 4 | +# |
| 5 | +# unit test: t7900 |
| 6 | + |
| 7 | +test -z "$DDDEBUG" || set -x |
| 8 | + |
| 9 | +_verbose=0 |
| 10 | + |
| 11 | +SUBDIRECTORY_OK=Yes |
| 12 | +OPTIONS_KEEPDASHDASH= |
| 13 | +OPTIONS_STUCKLONG=t |
| 14 | +# Would be nice to have examples, but rev-parse sees '*' as a symbol to hide everything afterwards |
| 15 | +#e,ext add relative path for any file of that type (ex. path/to/*.ext) |
| 16 | +#E,all-ext all files of that extention anywhere (ex. **/*.ext) |
| 17 | +#d,dir all files under the parent directory (ex. directory/*) |
| 18 | +#a,all-file all files of that file name (ex. **/filename.ext) |
| 19 | +OPTIONS_SPEC="git ignore [options] [file|glob ...] |
| 20 | +-- |
| 21 | + Miscelleneous |
| 22 | +edit open the pertinent gitignore with your default text editor (Requires \$EDITOR to be set) |
| 23 | +v,verbose show verbose output |
| 24 | +n,dry-run do not actually edit any .gitignore files |
| 25 | + Determine what files to add to the gitignore(s): |
| 26 | +e,ext add relative path for any file of that type |
| 27 | +E,all-ext all files of that extention anywhere |
| 28 | +d,dir all files under the parent directory |
| 29 | +a,all-file all files of that file name |
| 30 | + Determine what gitignore(s) to use: |
| 31 | +p,parent-level= number of parent directories containing the gitignore to edit. Set to 0 to put it in the local directory" |
| 32 | + |
| 33 | +. git-sh-setup |
| 34 | +. git-sh-i18n |
| 35 | + |
| 36 | +write_output () { |
| 37 | + if test $_verbose -eq 1 |
| 38 | + then |
| 39 | + say $1 |
| 40 | + fi |
| 41 | +} |
| 42 | + |
| 43 | +get_git_ignore () { |
| 44 | + directory=$1 |
| 45 | + |
| 46 | + # if we don't yet have the repo root directory, get it |
| 47 | + if test -z "$repo_root" |
| 48 | + then |
| 49 | + #First, determine the root of the repository |
| 50 | + repo_root="$(git rev-parse --show-toplevel)/" |
| 51 | + write_output "repo_root=$repo_root" |
| 52 | + fi |
| 53 | + |
| 54 | + # get the path relative to the repo root |
| 55 | + rel_directory="${directory#$repo_root}" |
| 56 | + # if the relative path is the same as it was, try converting it to aa *nix |
| 57 | + # style path |
| 58 | + if test "$rel_directory" = "$directory" |
| 59 | + then |
| 60 | + # repo root 2 (cygwin-ified path) didn't work |
| 61 | + # try the other one |
| 62 | + write_output "changing repo_root from $repo_root" |
| 63 | + #On windows, this turns to C:\... instead of /c/... from some other commands |
| 64 | + repo_root=$(printf "$repo_root" | awk -F":" '{ if ($2) print "/" tolower($1) $2; else print $1 }') |
| 65 | + write_output " to $repo_root" |
| 66 | + rel_directory="${directory#$repo_root}" |
| 67 | + fi |
| 68 | + # default gitignore |
| 69 | + gitignore="${repo_root}.gitignore" |
| 70 | + |
| 71 | + # ------------------------------------------------ |
| 72 | + # Determine the correct git ignore and the path of |
| 73 | + # the file relative to it |
| 74 | + # ------------------------------------------------ |
| 75 | + if test $_parent_level -ge 0 |
| 76 | + then |
| 77 | + parent=${directory} |
| 78 | + write_output "parent=${parent}" |
| 79 | + |
| 80 | + if test $_parent_level -ne 0 |
| 81 | + then |
| 82 | + i=1 |
| 83 | + while test "$i" -le $_parent_level |
| 84 | + do |
| 85 | + parent="$(dirname "$parent")/" |
| 86 | + write_output "parent=${parent}" |
| 87 | + i=$(($i + 1)) |
| 88 | + done |
| 89 | + fi |
| 90 | + root_len=$(printf "${repo_root}" | wc -m) |
| 91 | + parent_len=$(printf "${parent}" | wc -m) |
| 92 | + if test $root_len -ge $parent_len |
| 93 | + then |
| 94 | + write_output "root_len(${root_len}) >= parent_len(${parent_len})... |
| 95 | + uh-oh" |
| 96 | + gettextln "WARNING: Parent directory is outside of the repository" |
| 97 | + parent="${repo_root}" |
| 98 | + else |
| 99 | + write_output "root_len(${root_len}) < parent_len(${parent_len})... |
| 100 | + good" |
| 101 | + fi |
| 102 | + rel_directory="${directory#$parent}" |
| 103 | + gitignore="${parent}.gitignore" |
| 104 | + fi |
| 105 | + |
| 106 | + write_output "rel_directory=${rel_directory}" |
| 107 | + write_output "gitignore=${gitignore}" |
| 108 | + |
| 109 | +} |
| 110 | + |
| 111 | +add_ignore () { |
| 112 | + # get the absolute path of the file |
| 113 | + file="$(cd "$(dirname "$1")"; pwd)/$(basename "$1")" |
| 114 | + write_output "file=$file" |
| 115 | + |
| 116 | + directory="$(dirname "$file")/" |
| 117 | + write_output "directory=$directory" |
| 118 | + get_git_ignore "$directory" |
| 119 | + |
| 120 | + filename=$(basename "$file") |
| 121 | + write_output "filename=$filename" |
| 122 | + extension="${filename##*.}" |
| 123 | + write_output "extension=$extension" |
| 124 | + # defaault line |
| 125 | + line="${rel_directory}${filename}" |
| 126 | + |
| 127 | + # ------------------------------------------------ |
| 128 | + # Determine the correct line to add to the gitignore |
| 129 | + # based on user inputs |
| 130 | + # ------------------------------------------------ |
| 131 | + if test $_ext -eq 1 |
| 132 | + then |
| 133 | + line="${rel_directory}*.$extension" |
| 134 | + fi |
| 135 | + if test $_directory -eq 1 |
| 136 | + then |
| 137 | + line="${rel_directory}*" |
| 138 | + fi |
| 139 | + if test $_file_anywhere -eq 1 |
| 140 | + then |
| 141 | + line="**/$filename" |
| 142 | + fi |
| 143 | + if test $_ext_anywhere -eq 1 |
| 144 | + then |
| 145 | + line="**/*.$extension" |
| 146 | + fi |
| 147 | + write_output "line=${line}" |
| 148 | + dryrun="" |
| 149 | + if test $_dry_run -eq 1 |
| 150 | + then |
| 151 | + dryrun="$(gettext "DRY-RUN!")" |
| 152 | + fi |
| 153 | + say "$dryrun $(eval_gettext "Adding \$line to \$gitignore")" |
| 154 | + if test $_dry_run -eq 0 |
| 155 | + then |
| 156 | + echo "$line" >>"$gitignore" |
| 157 | + fi |
| 158 | +} |
| 159 | + |
| 160 | +_ext=0 |
| 161 | +_directory=0 |
| 162 | +_file_anywhere=0 |
| 163 | +_ext_anywhere=0 |
| 164 | +_parent_level=-1 |
| 165 | +_edit=0 |
| 166 | +_dry_run=0 |
| 167 | + |
| 168 | +while test $# != 0 |
| 169 | +do |
| 170 | + case "$1" in |
| 171 | + --ext) |
| 172 | + _ext=1 |
| 173 | + ;; |
| 174 | + --all-ext) |
| 175 | + _ext_anywhere=1 |
| 176 | + ;; |
| 177 | + --dir) |
| 178 | + _directory=1 |
| 179 | + ;; |
| 180 | + --all-file) |
| 181 | + _file_anywhere=1 |
| 182 | + ;; |
| 183 | + --parent-level=*) |
| 184 | + _parent_level="${1#--parent-level=}" |
| 185 | + if ! echo $_parent_level | grep -q '^[0-9]\+$' |
| 186 | + then |
| 187 | + gettextln "ILLEGAL PARAMETER: -p|--parent-level requires a numerical argument" |
| 188 | + usage |
| 189 | + fi |
| 190 | + ;; |
| 191 | + --dry-run) |
| 192 | + _dry_run=1 |
| 193 | + ;; |
| 194 | + --edit) |
| 195 | + if test -z $EDITOR |
| 196 | + then |
| 197 | + gettextln "ERROR: Shell variable \$EDITOR must be set" |
| 198 | + usage |
| 199 | + fi |
| 200 | + _edit=1 |
| 201 | + ;; |
| 202 | + --verbose) |
| 203 | + _verbose=1 |
| 204 | + ;; |
| 205 | + --) |
| 206 | + only_files_left=1 |
| 207 | + ;; |
| 208 | + *) |
| 209 | + if test $only_files_left -eq 1 |
| 210 | + then |
| 211 | + add_ignore "$1" |
| 212 | + fi |
| 213 | + ;; |
| 214 | + esac |
| 215 | + shift |
| 216 | +done |
| 217 | +if test $_edit -eq 1 |
| 218 | +then |
| 219 | + get_git_ignore "$(pwd)/" |
| 220 | + git_editor "$gitignore" |
| 221 | +fi |
| 222 | +exit 0 |
0 commit comments