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