bugfixes, features, documentation, examples, new tool
[hband-tools.git] / user-tools / mkdeb
blobf01fe8d814c6d0a2c7a42928e37ee9ed0b30f706
1 #!/bin/bash -e
3 true <<EOF
4 =pod
6 =head1 NAME
8 mkdeb - Create a Debian package (.deb)
10 =head1 SYNOPSIS
12 mkdeb [-m | --multiarch]
14 =head1 DESCRIPTION
16 Create a *.deb file according to the package name and version info found in F<./deb/DEBIAN/control> file
17 and include all file in the package found in F<./deb> folder. Update some of C<control> file's fields, eg.
18 C<Version> (increase by 1 if there is any file in the package newer than C<control> file), C<Installed-Size>...
20 In I<multiarch> mode, instead of F<./deb> folder, it takes data from all folders in the current working
21 directory which name is a valid Debian architecture name (eg. amd64, i386, ...), and stores temporary
22 files in F<./deb> for building each architecture's package.
24 Mkdeb also considers C<mkdeb-perms.txt> file in the current working directory to set
25 some file attributes in the package, otherwise all file attributes are gonna be the same as on the original.
26 Each line in this file looks like:
28 <B<MODE>> <B<OWNER>> <B<GROUP>> <B<PATH>>
30 Where
32 =over 8
34 =item <B<MODE>>
36 is an octal file permission mode, 3 or 4 digits, or "-" to ignore
38 =item <B<OWNER>>
40 UID or name of the owner user
42 =item <B<GROUP>>
44 GID or name of the owner group
46 =item <B<PATH>>
48 the file's path itself to which the attributes are applied, relative to F<./deb> directory.
50 =back
52 =cut
54 EOF
57 declare -a archs
58 archs=(amd64 armel armhf hurd-i386 i386 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc s390x sparc)
59 mode=simple
61 main()
63 fakeroot_opt=''
65 for attrib in Package Version Architecture
67 value=$(grep -E ^$attrib: deb/DEBIAN/control | cut -f2- -d' ')
68 eval $attrib=\$value
69 done
71 # Package modified since last build?
72 if [ -n "$(find deb -type f -newer deb/DEBIAN/control ! -path "deb/DEBIAN/*" -print -quit)" ]
73 then
74 Version_new=`echo "$Version" | perl -pe 's/^(.*?)(\d+)([^\d]*)$/$1.($2+1).$3/e;'`
75 echo "Increase version number $Version -> $Version_new" >&2
76 Version=$Version_new
79 size=`du -s deb/ | awk '{print $1}'`
80 sed -e "s/^Installed-Size:.*/Installed-Size: $size/" -i deb/DEBIAN/control
81 sed -e "s/^Version:.*/Version: $Version/" -i deb/DEBIAN/control
83 find deb/ -type f -exec md5sum -b {} \; -or -path "deb/DEBIAN" -prune | sed -e 's@\*\?deb/@@' > deb/DEBIAN/md5sums
85 if [ -f mkdeb-perms.txt ]
86 then
87 # Create fakeroot environment
88 devnum=`stat -c %D deb/`
89 while read -r mode owner group filepath
91 [ -z "$filepath" -o "${mode:0:1}" = '#' ] && continue
92 filepath="deb/$filepath"
93 inode=`stat -c %i "$filepath"`
94 nlink=`stat -c %h "$filepath"`
96 fullmode=$(printf %06o 0x`stat -c %f "$filepath"`)
97 if [ "$mode" = - ]
98 then
99 mode=$fullmode
100 else
101 mode65=${fullmode:0:2}
102 [ "${#mode}" -lt 4 ] && mode4=0
103 mode=${mode65}${mode4}${mode}
105 if [ "$owner" = - ]
106 then
107 uid=0
108 else
109 [ "$owner" -ge 0 ] 2>/dev/null && uid=$owner || uid=`id -u $owner`
111 if [ "$group" = - ]
112 then
113 gid=0
114 else
115 [ "$group" -ge 0 ] 2>/dev/null && gid=$group || gid=`getent group $group | cut -d: -f3`
118 echo dev=$devnum,ino=$inode,mode=$mode,uid=$uid,gid=$gid,nlink=$nlink,rdev=0
119 done <mkdeb-perms.txt >mkdeb-fakeroot.txt
120 fakeroot_opt="-i mkdeb-fakeroot.txt"
123 # Sanity Check
124 #\( \( ! -perm -0444 -o -perm /0002 \) -o \( -type d ! -perm -0111 \) \)
125 if [ -e deb/usr/ ]
126 then
127 fakeroot $fakeroot_opt find deb/usr/ ! -perm -0444 -printf "WARN: File/dir is not readable for everybody: %p\n"
128 fakeroot $fakeroot_opt find deb/usr/ ! -type l -perm /0002 -printf "WARN: File/dir is writable for others: %p\n"
129 fakeroot $fakeroot_opt find deb/usr/ -type d ! -perm -0111 -printf "WARN: Dir is not searchable for everybody: %p\n"
130 fi >&2
132 # Create Package
133 pkgfile="${Package}_${Version}_${Architecture}.deb"
134 fakeroot $fakeroot_opt dpkg-deb -b deb/ "$pkgfile"
139 while [ -n "$1" ]
141 case "$1" in
142 -h|--help)
143 echo "$0: Create debian package
144 1. Simple mode, store contents of \`deb/' directory in a properly named file.
145 \$ $0
146 2. Make as many packages as many directories it find with name of standard
147 architecture names (eg. amd64, i386). Files in special folder \`all' will be
148 included in all packages.
149 \$ $0 --multiarch"
150 exit
153 -m|--multiarch)
154 mode=multiarch
156 esac
157 shift
158 done
161 if [ "$mode" = multiarch ]
162 then
163 if [ -d deb/ ]
164 then
165 echo "Subfolder \`deb/' already exists. Multiarch mode would work into it. Please remove." >&2
166 exit 1
169 for arch in "${archs[@]}"
171 if [ -d "$arch" ]
172 then
173 echo "Architecture: $arch" >&2
174 mkdir deb/
175 cp -aT all/ deb/
177 reffile=deb/DEBIAN/control.ref
178 touch -r all/DEBIAN/control "$reffile"
180 cp -aT "$arch/" deb/
181 sed -e "s/^Architecture:.*/Architecture: $arch/" -i deb/DEBIAN/control
183 touch -r "$reffile" deb/DEBIAN/control
184 rm "$reffile"
186 main
187 rm -r deb/
189 done
190 else
191 main