nonzero result on modification
[cedit] / cedit
1 #!/bin/bash
2 # Copyright (C) 2016 Ian Kelling
3
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7
8 # http://www.apache.org/licenses/LICENSE-2.0
9
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 cedit() {
17 local help="Usage: [-h|--help ] [-v] [SECTION_NAME] FILE
18 Create/modify a section in a config file
19
20 Returns 1 if the file is modified by this command, 2 or higher
21 for other problems.
22
23 The section is #comment delimited. Reads STDIN for the contents of the
24 section. Without SECTION_NAME, it acts on a global unnamed
25 section. cedit is short for config edit.
26
27 -v Verbose
28 -h|--help Help"
29 local s diff name init
30 local file_dir="$(dirname "$file")"
31 local exists=true
32 local verbose=false
33
34 case $1 in
35 -v) verbose=true; shift ;;
36 -h|--help) echo "$help"; return ;;
37 esac
38
39 if (( $# == 2 )); then
40 name=": $1"
41 shift
42 fi
43
44 local file="$1"
45 local file_name="${file##*/}"
46
47 local begin="#_#_# start delimiter of cedit section$name. do not modify. #_#_#"
48 local end="#_#_# end delimiter of cedit section$name. do not modify. #_#_#"
49
50 if [[ ! -e $file_dir ]]; then
51 if ! mkdir -p $file_dir; then
52 s=sudo
53 $s mkdir -p $file_dir || return 2
54 fi
55 fi
56 if [[ ! -e $file ]]; then
57 exists=false
58 if ! $s touch $file; then
59 s=sudo
60 $s touch $file || return 2
61 fi
62 fi
63
64 [[ -w $file ]] || s=sudo
65
66
67 if $exists; then
68 local temp="$(mktemp -d)/$file_name"
69 cp "$file" "$temp"
70 cp /dev/null "$file"
71 local in_section=false
72 while IFS= read -r line; do
73 if [[ $line == $begin ]]; then
74 in_section=true;
75 fi
76 if ! $in_section; then
77 printf '%s\n' "$line" >> $file
78 fi
79 if [[ $line == $end ]]; then
80 in_section=false;
81 fi
82 done < "$temp"
83 fi
84
85 IFS= read -d '' -n 1 -r init
86 if [[ $init ]]; then
87 $s tee -a "$file" >/dev/null <<<"$begin"
88 printf '%s' "$init" | $s tee -a "$file" >/dev/null
89 $s tee -a "$file" >/dev/null
90 $s tee -a "$file" >/dev/null <<<"$end"
91 fi
92
93 if ! $exists; then
94 ret=1
95 if $verbose; then
96 echo "New file $file:"
97 cat "$file"
98 fi
99 elif type -t diff &>/dev/null; then
100 diff=$(diff -u "$temp" "$file")
101 ret=$?
102 if $verbose; then
103 if (( $ret == 0 )); then
104 echo "No changes made to $file"
105 fi
106 else
107 echo "backup of original at $temp"
108 echo diff -u "$temp" "$file":
109 echo "$diff"
110 fi
111 else
112 # for systems like openwrt which don't have diff
113 diff=$(cmp "$temp" "$file")
114 ret=$?
115 if $verbose; then
116 echo "$diff"
117 fi
118 fi
119 return $ret
120 }
121 cedit "$@"