Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 210 lines (179 sloc) 6.119 kb
e59261f @rtomayko split package registration and installation into separate programs
authored
1 #!/bin/sh
2 # The `rpg-package-install` program perform the actual installation of files
3 # into the system installation locations. The `<package>` and `<version>`
4 # supplied must already be registered in the package database as by invoking
5 # the `rpg-package-register` program.
6 #
7 # If the package is already installed and at the version specified,
8 # `rpg-package-install` exits immediately with a success exit status. The
9 # `-f` argument can be used to force the install operations to be performed
10 # on an already installed program.
11 set -e
12 . rpg-sh-setup
13
14 [ "$*" ] || set -- '--help'; ARGV="$@"
15 USAGE '${PROGNAME} [-f] <package> <version> ...
16 Install a registered package from the database.
17
18 This is a low level command. For an install front-end, see rpg-install(1).'
19
20 force=false
21 test "$1" = '-f' && {
22 force=true
23 shift
24 }
25
26 [ "$1$2" ] || {
27 warn "invalid arguments: '$*'";
28 exit 2
29 }
30
31 # Utility Functions
32 # -----------------
33
34 # Usage: rpg_ln <source> <dest>
35 # Attempt to hard link <dest> to <source> but fall back to cp(1) if
36 # you're crossing file systems or the ln fails otherwise.
37 rpg_ln () {
38 if ln -f "$1" "$2"
39 then notice "$2 [ln]"
40 else notice "$2 [cp]"
41 cp "$1" "$2"
42 fi
43 }
44
45 # Recursive file hierarchy copy routine. Attempts to hardlink files
46 # and falls back to normal copies.
47 rpg_install_dir () {
48 local src="$1" dest="$2" manifest="$3"
49 mkdir -p "$dest"
50 for file in "$1"/*
51 do
52 if test -f "$file"
53 then # link dest to source
54 rpg_ln "$file" "$dest/$(basename $file)"
55 echo "$dest/$(basename $file)" >> "$manifest"
56
57 elif test -d "$file"
58 then # recurse into directories
59 rpg_install_dir "$file" "$dest/$(basename $file)" "$manifest"
60
61 else warn "unknown file type: $file"
62 return 1
63 fi
64 done
65 return 0
66 }
67
68 # Package Database Prep
69 # ---------------------
70
71 # Establish our directories in the package database. These should
72 # have already been created by `rpg-package-register`. If not, bail
73 # out now since something isn't right.
74 package="$1"
75 version="$2"
76 packagedir="$RPGDB/$package"
77
78 test -d "$packagedir/$version" || {
79 warn "package not registered: $package/$version"
80 exit 1
81 }
82
83 notice "$package $version"
84
85 # Fetch the gem into the cache and unpack into the packs area if
86 # its not already there.
87 if test -d "$RPGPACKS/$package-$version"
88 then notice "sources already exist. bypassing fetch and unpack."
89 else gemfile=$(rpg-fetch "$package" "$version")
90 notice "unpacking $gemfile into $RPGPACKS"
91 mkdir -p "$RPGPACKS"
92 (cd "$RPGPACKS" && gem unpack "$gemfile" >/dev/null)
93 fi
94
95 # If the package already has an active/installed version, check if its
96 # the same as the one we're installing and bail if so. Otherwise unlink
97 # the active version and install over it for now.
98 #
99 # TODO handle uninstalling previous package version or fail or something.
100 test -e "$packagedir/active" && {
101 activevers=$(readlink $packagedir/active)
102 if test "$activevers" = "$version"
103 then
104 if $force
105 then notice "$package $version is current. reinstalling due to -f"
106 unlink "$packagedir/active"
107 else notice "$package $version is current. not reinstalling."
108 exit 0
109 fi
110 else notice "$package $activevers is installed but $version requested"
111 unlink "$packagedir/active"
112 fi
113 }
114
115 # This is our file manifest. We record everything installed in here
116 # so we know how to uninstall the package. Create/truncate it in case
117 # it already exists.
118 #
119 # TODO if the manifest already exists that means the package was
120 # previously installed or may currently be installed. Do something with
121 # that information.
122 manifest="$packagedir/$version/manifest"
123 echo "# $(date)" > "$manifest"
124
125 # Symlink the `installing` file to the version directory. This will let us
126 # detect in progress or failed installations.
127 ln -sf "$version" "$packagedir/installing"
128
129 # Go into the unpackaged package dir to make installing a bit easier.
130 cd "$RPGPACKS/$package-$version"
131
132
133 # Extension Libraries
134 # -------------------
135
136 # Build extension libraries if they exist. Bail out if the build fails.
137 exts="$(rpg-build "$(pwd)")" || {
138 warn "extension failed to build"
139 exit 1
140 }
141
142 # Install any extensions to `RPGLIB`. This is kind of tricky. We should
143 # be running `make` in the extension directory but I haven't had time to
144 # make it work right so just pull the prefix out of the `Makefile` and
145 # install the shared libs manually.
146 test -n "$exts" && {
147 mkdir -p "$RPGLIB"
148 echo "$exts" |
149 while read dl
150 do
151 # make install sitearchdir=/lib
152 prefix=$(
153 grep '^target_prefix.=' "$(dirname $dl)/Makefile" |
154 sed 's/^target_prefix *= *//'
155 )
156 dest="${RPGLIB}${prefix}/$(basename $dl)"
157 rpg_ln "$dl" "$dest"
158 echo "$dest" >> "$manifest"
159 done
160 }
161
162 # Ruby Library Files
163 # ------------------
164
165 # Recursively install all library files into `RPGLIB`.
166 test -d lib && {
167 mkdir -p "$RPGLIB"
168 rpg_install_dir lib "$RPGLIB" "$manifest"
169 }
170
171 # Ruby Executables
172 # ----------------
173
174 # Write executable scripts into `RPGBIN` and rewrite shebang lines.
175 test -d bin && {
176 mkdir -p "$RPGBIN"
177 for file in bin/*
178 do dest="$RPGBIN/$(basename $file)"
179 notice "$dest [!]"
180 sed "s@^#!.*ruby.*@#!$(ruby_command)@" \
181 < "$file" \
182 > "$dest"
183 chmod 0755 "$dest"
184 echo "$dest" >> "$manifest"
185 done
186 }
187
188 # Manpages
189 # --------
190
191 # Install any manpages included with the package into `RPGMAN`. Make
192 # sure files are being installed under the prescribed hierarchy.
193 test -d man && {
194 for file in man/*
195 do if test -f "$file" && expr "$file" : '.*\.[0-9][0-9A-Za-z]*$' >/dev/null
196 then
197 section=${file##*\.}
198 dest="$RPGMAN/man$section/$(basename $file)"
199 mkdir -p "$RPGMAN/man$section"
200 rpg_ln "$file" "$dest"
201 echo "$dest" >> "$manifest"
202 fi
203 done
204 }
205
206
207 # Mark this package as active
208 unlink "$packagedir/installing"
209 ln -sf "$version" "$packagedir/active"
Something went wrong with that request. Please try again.