GNU bug report logs - #44626
tests/build-utils, tests/guix-system: fail when build path contains "~"

Previous Next

Package: guix;

Reported by: Vagrant Cascadian <vagrant <at> debian.org>

Date: Sat, 14 Nov 2020 02:00:02 UTC

Severity: normal

Done: Ludovic Courtès <ludo <at> gnu.org>

Bug is archived. No further changes may be made.

To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 44626 in the body.
You can then email your comments to 44626 AT debbugs.gnu.org in the normal way.

Toggle the display of automated, internal messages from the tracker.

View this report as an mbox folder, status mbox, maintainer mbox


Report forwarded to bug-guix <at> gnu.org:
bug#44626; Package guix. (Sat, 14 Nov 2020 02:00:02 GMT) Full text and rfc822 format available.

Acknowledgement sent to Vagrant Cascadian <vagrant <at> debian.org>:
New bug report received and forwarded. Copy sent to bug-guix <at> gnu.org. (Sat, 14 Nov 2020 02:00:02 GMT) Full text and rfc822 format available.

Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):

From: Vagrant Cascadian <vagrant <at> debian.org>
To: bug-guix <at> gnu.org
Subject: tests/build-utils,
 tests/guix-system: fail when build path contains "~"
Date: Fri, 13 Nov 2020 17:58:46 -0800
[Message part 1 (text/plain, inline)]
When building from a build path containing a "~", such as:

  /build/guix-1WL3Dl/guix-1.2.0~rc1/

tests/build-utils.scm and tests/guix-system.sh both fail.

I've observed this with v1.2.0rc1, as well as
c6e8f40f2ce6082171c18b4aad9877b0ad022563.

Building in such a directory revealed two failing tests, which I could
reproduce attempting to run the tests directly from a directory that
such as /home/vagrant/src/guix~tilde/ using "guix environment --pure
guix":

  make -j2 check RES_OPTIONS=attempts:0 AM_SCM_LOG_DRIVER_FLAGS="--brief=no" TESTS="tests/build-utils.scm tests/guix-system.sh"

Running the same tests in /home/vagrant/src/guix-tilde PASSed.

(FWIW, The version is renamed in Debian so that release candidates such
are treated as older versions than the eventual released version
(e.g. 1.2.0rc1 > 1.2.0 > 1.2.0~rc1 for Debian package versions) and it
would be best for Debian to be able to use the ~ in the Debian package
version)


FAIL: tests/build-utils
=======================
...
test-name: wrap-script, simple case
location: /<<PKGBUILDDIR>>/tests/build-utils.scm:152
source:
+ (test-equal
+   "wrap-script, simple case"
+   (string-append
+     (format
+       #f
+       "#!~a --no-auto-compile\n#!#; Guix wrapper\n#\\-~s\n#\\-~s\n"
+       (which "guile")
+       '(begin
+          (let ((current (getenv "GUIX_FOO")))
+            (setenv
+              "GUIX_FOO"
+              (if current
+                (string-append
+                  "/some/path:/some/other/path"
+                  ":"
+                  current)
+                "/some/path:/some/other/path"))))
+       '(let ((cl (command-line)))
+          (apply execl
+                 "/anything/cabbage-bash-1.2.3/bin/sh"
+                 (car cl)
+                 (cons (car cl) (append '("") cl)))))
+     script-contents)
+   (call-with-temporary-directory
+     (lambda (directory)
+       (let ((script-file-name
+               (string-append directory "/foo")))
+         (call-with-output-file
+           script-file-name
+           (lambda (port) (format port script-contents)))
+         (chmod script-file-name 511)
+         (wrap-script
+           script-file-name
+           `("GUIX_FOO"
+             prefix
+             ("/some/path" "/some/other/path")))
+         (let ((str (call-with-input-file
+                      script-file-name
+                      get-string-all)))
+           (with-directory-excursion
+             directory
+             (delete-file "foo"))
+           str)))))
FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
        destination: #<input-output: /tmp/guix-directory.s4eviV/foo.tD6mtU 8>
        format string: "#!/<<PKGBUILDDIR>>/guile --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current (string-append \"/some/path:/some/other/path\" \":\" current) \"/some/path:/some/other/path\"))))\n#\\-(let ((cl (command-line))) (apply execl \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl) (append (quote (\"\")) cl))))\n"
        format args: ()
        error args:  (#f "error in format" () #f)
FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
        destination: #<input-output: /tmp/guix-directory.s4eviV/foo.tD6mtU 8>
        format string: "#!/<<PKGBUILDDIR>>/guile --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current (string-append \"/some/path:/some/other/path\" \":\" current) \"/some/path:/some/other/path\"))))\n#\\-(let ((cl (command-line))) (apply execl \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl) (append (quote (\"\")) cl))))\n"
        format args: ()
        error args:  (#<&wrap-error program: "/tmp/guix-directory.s4eviV/foo" type: misc-error>)
expected-value: "#!/<<PKGBUILDDIR>>/guile --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current (string-append \"/some/path:/some/other/path\" \":\" current) \"/some/path:/some/other/path\"))))\n#\\-(let ((cl (command-line))) (apply execl \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl) (append (quote (\"\")) cl))))\n#!/anything/cabbage-bash-1.2.3/bin/sh\n\necho hello world"
actual-value: #f
actual-error:
+ (%exception
+   #<&wrap-error program: "/tmp/guix-directory.s4eviV/foo" type: misc-error>)
result: FAIL


FAIL: tests/guix-system
=======================

+ set -e
+ guix system --version
guix system (GNU Guix) 1.2.0rc1
Copyright (C) 2020 the Guix authors
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
+ tmpfile=t-guix-system-6249
+ errorfile=t-guix-system-error-6249
+ tmpdir=/tmp/t-guix-system-6249
+ mkdir /tmp/t-guix-system-6249
+ trap 'rm -f "$tmpfile" "$errorfile" "$tmpdir"/*; rmdir "$tmpdir"' EXIT
+ cat
+ guix system vm t-guix-system-6249
+ grep 't-guix-system-6249:2:3:.*missing.* initializers' t-guix-system-error-6249
t-guix-system-6249:2:3: error: (operating-system): missing field initializers (bootloader host-name file-systems timezone)
+ cat
+ guix system vm t-guix-system-6249
+ grep 't-guix-system-6249:4:1: missing closing paren' t-guix-system-error-6249
t-guix-system-6249:4:1: missing closing parenthesis
+ cat
+ guix system build t-guix-system-6249 -n
+ grep 't-guix-system-6249:3:2: .*module .*openssh.*not found' t-guix-system-error-6249
t-guix-system-6249:3:2: error: module (gnu services openssh) not found
+ grep 'Try.*use-service-modules ssh' t-guix-system-error-6249
hint: Try adding `(use-service-modules ssh)'.
+ cat
+ guix system build t-guix-system-6249 -n
+ grep 't-guix-system-6249:3:2: .*module .*qemu.*not found' t-guix-system-error-6249
t-guix-system-6249:3:2: error: module (gnu packages qemu) not found
+ grep 'Try.*use-package-modules virtualization' t-guix-system-error-6249
hint: Try adding `(use-package-modules virtualization)'.
+ cat
+ guix system build t-guix-system-6249 -n
++ guile -c '(display (effective-version))'
+ test 3.0 = 3.0
+ grep 't-guix-system-6249:[0-9]\+:[0-9]\+:.*GRUB-config.*[Uu]nbound variable' t-guix-system-error-6249
t-guix-system-6249:9:14: error: GRUB-config: unbound variable
+ cat
+ guix system build t-guix-system-6249 -n
+ grep 't-guix-system-6249:3:[0-9]\+:.*%base-file-system.*invalid field specifier' t-guix-system-error-6249
t-guix-system-6249:3:0: error: %base-file-systems: invalid field specifier
+ OS_BASE='
  (host-name "antelope")
  (timezone "Europe/Paris")
  (locale "en_US.UTF-8")

  (bootloader (bootloader-configuration
               (bootloader grub-bootloader)
               (target "/dev/sdX")))
  (file-systems (cons (file-system
                        (device (file-system-label "root"))
                        (mount-point "/")
                        (type "ext4"))
                      %base-file-systems))
'
+ cat
+ guix system vm t-guix-system-6249
accepted connection from pid 6412, user vagrant
+ grep 'service '\''networking'\''.*more than once' t-guix-system-error-6249
guix system: error: service 'networking' provided more than once
+ cat
+ guix system build t-guix-system-6249
accepted connection from pid 6433, user vagrant
+ grep 'service '\''buggy!'\''.*'\''does-not-exist'\''.*not provided' t-guix-system-error-6249
guix system: error: service 'buggy!' requires 'does-not-exist', which is not provided by any service
+ make_user_config users wheel
+ cat
+ guix system build t-guix-system-6249 -n
accepted connection from pid 6454, user vagrant
guix system: error: invalid character `~' in name `shepherd-file-system--build-guix-1WL3Dl-guix-1.2.0~rc1-test-tmp-store.scm-builder'
+ rm -f t-guix-system-6249 t-guix-system-error-6249 '/tmp/t-guix-system-6249/*'
+ rmdir /tmp/t-guix-system-6249
FAIL tests/guix-system.sh (exit status: 1)


live well,
  vagrant
[signature.asc (application/pgp-signature, inline)]

Reply sent to Ludovic Courtès <ludo <at> gnu.org>:
You have taken responsibility. (Mon, 16 Nov 2020 11:58:02 GMT) Full text and rfc822 format available.

Notification sent to Vagrant Cascadian <vagrant <at> debian.org>:
bug acknowledged by developer. (Mon, 16 Nov 2020 11:58:02 GMT) Full text and rfc822 format available.

Message #10 received at 44626-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vagrant Cascadian <vagrant <at> debian.org>
Cc: 44626-done <at> debbugs.gnu.org
Subject: Re: bug#44626: tests/build-utils, tests/guix-system: fail when
 build path contains "~"
Date: Mon, 16 Nov 2020 12:57:06 +0100
Hi!

Vagrant Cascadian <vagrant <at> debian.org> skribis:

> When building from a build path containing a "~", such as:
>
>   /build/guix-1WL3Dl/guix-1.2.0~rc1/
>
> tests/build-utils.scm and tests/guix-system.sh both fail.

[...]

> FAIL: tests/build-utils
> =======================
> ...
> test-name: wrap-script, simple case
> location: /<<PKGBUILDDIR>>/tests/build-utils.scm:152
> source:
> + (test-equal
> +   "wrap-script, simple case"

[…]

> + make_user_config users wheel
> + cat
> + guix system build t-guix-system-6249 -n
> accepted connection from pid 6454, user vagrant
> guix system: error: invalid character `~' in name `shepherd-file-system--build-guix-1WL3Dl-guix-1.2.0~rc1-test-tmp-store.scm-builder'

I believe both are fixed by 977eb5d023cfdf8e336f1896480eea9cef5c04e9.

Note that another solution to sidestep those issues would have been to
use a test store that doesn’t contain ‘~’, like so:

  ./configure ac_cv_guix_test_root=/tmp/build-guix…/store

Thanks!

Ludo’.




Information forwarded to bug-guix <at> gnu.org:
bug#44626; Package guix. (Tue, 17 Nov 2020 03:28:01 GMT) Full text and rfc822 format available.

Message #13 received at 44626 <at> debbugs.gnu.org (full text, mbox):

From: Vagrant Cascadian <vagrant <at> debian.org>
To: Ludovic Courtès <ludo <at> gnu.org>
Cc: 44626 <at> debbugs.gnu.org
Subject: Re: bug#44626: tests/build-utils,
 tests/guix-system: fail when build path contains "~"
Date: Mon, 16 Nov 2020 19:26:53 -0800
[Message part 1 (text/plain, inline)]
On 2020-11-16, Ludovic Courtès wrote:
> Vagrant Cascadian <vagrant <at> debian.org> skribis:
>
>> When building from a build path containing a "~", such as:
>>
>>   /build/guix-1WL3Dl/guix-1.2.0~rc1/
>>
>> tests/build-utils.scm and tests/guix-system.sh both fail.
>
> [...]
>
>> FAIL: tests/build-utils
>> =======================
>> ...
>> test-name: wrap-script, simple case
>> location: /<<PKGBUILDDIR>>/tests/build-utils.scm:152
>> source:
>> + (test-equal
>> +   "wrap-script, simple case"
>
> […]
>
>> + make_user_config users wheel
>> + cat
>> + guix system build t-guix-system-6249 -n
>> accepted connection from pid 6454, user vagrant
>> guix system: error: invalid character `~' in name `shepherd-file-system--build-guix-1WL3Dl-guix-1.2.0~rc1-test-tmp-store.scm-builder'
>
> I believe both are fixed by 977eb5d023cfdf8e336f1896480eea9cef5c04e9.

Thanks for the quick fix! That seems to fix tests/guix-system.sh...

Though may introduce a different issue in tests/build-utils.log:

...
test-name: wrap-script, simple case
location: /build/guix-41NMGX/guix-1.2.0~rc1/tests/build-utils.scm:152
source:
+ (test-equal
+   "wrap-script, simple case"
+   (string-append
+     (format
+       #f
+       "#!~a --no-auto-compile\n#!#; Guix wrapper\n#\\-~s\n#\\-~s\n"
+       (which "guile")
+       '(begin
+          (let ((current (getenv "GUIX_FOO")))
+            (setenv
+              "GUIX_FOO"
+              (if current
+                (string-append
+                  "/some/path:/some/other/path"
+                  ":"
+                  current)
+                "/some/path:/some/other/path"))))
+       '(let ((cl (command-line)))
+          (apply execl
+                 "/anything/cabbage-bash-1.2.3/bin/sh"
+                 (car cl)
+                 (cons (car cl) (append '("") cl)))))
+     script-contents)
+   (call-with-temporary-directory
+     (lambda (directory)
+       (let ((script-file-name
+               (string-append directory "/foo")))
+         (call-with-output-file
+           script-file-name
+           (lambda (port) (display script-contents port)))
+         (chmod script-file-name 511)
+         (wrap-script
+           script-file-name
+           `("GUIX_FOO"
+             prefix
+             ("/some/path" "/some/other/path")))
+         (let ((str (call-with-input-file
+                      script-file-name
+                      get-string-all)))
+           (with-directory-excursion
+             directory
+             (delete-file "foo"))
+           str)))))
FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
        destination: #<input-output:
        /tmp/guix-directory.YrSRbV/foo.3efcPU 8>
        format string: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
        --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current
        (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current
        (string-append \"/some/path:/some/other/path\" \":\" current)
        \"/some/path:/some/other/path\"))))\n#\\-(let ((cl
        (command-line))) (apply execl
        \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl)
        (append (quote (\"\")) cl))))\n"
        format args: ()
        error args:  (#f "error in format" () #f)
FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
        destination: #<input-output:
        /tmp/guix-directory.YrSRbV/foo.3efcPU 8>
        format string: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
        --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current
        (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current
        (string-append \"/some/path:/some/other/path\" \":\" current)
        \"/some/path:/some/other/path\"))))\n#\\-(let ((cl
        (command-line))) (apply execl
        \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl)
        (append (quote (\"\")) cl))))\n"
        format args: ()
        error args:  (#<&wrap-error program:
        "/tmp/guix-directory.YrSRbV/foo" type: misc-error>)
expected-value: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
--no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current (getenv
\"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current (string-append
\"/some/path:/some/other/path\" \":\" current)
\"/some/path:/some/other/path\"))))\n#\\-(let ((cl (command-line)))
(apply execl \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car
cl) (append (quote (\"\"))
cl))))\n#!/anything/cabbage-bash-1.2.3/bin/sh\n\necho hello world"
actual-value: #f
actual-error:
+ (%exception
+   #<&wrap-error program: "/tmp/guix-directory.YrSRbV/foo" type:
misc-error>)
result: FAIL

test-name: wrap-script, with encoding declaration
...
result: PASS

test-name: wrap-script, raises condition
...
result: PASS


FORMAT: error with call: (format #<input-output:
/tmp/guix-directory.YrSRbV/foo.3efcPU 8>
"#!/build/guix-41NMGX/guix-1.2.0~r<===c1/guile --no-auto-compile
#!#; Guix wrapper
#\-(begin (let ((current (getenv "GUIX_FOO"))) (setenv "GUIX_FOO" (if
current (string-append "/some/path:/some/other/path" ":" current)
"/some/path:/some/other/path"))))
#\-(let ((cl (command-line))) (apply execl
"/anything/cabbage-bash-1.2.3/bin/sh" (car cl) (cons (car cl) (append
(quote ("")) cl))))
" ===>)
        missing argument(s)
wrap-script: /tmp/guix-directory.YrSRbV/foo: error: misc-error (#f
"error in format" () #f)


Not sure what test or where in the code that last error is coming
from...

Because I've added so many network-reachable/test-skip patches, it is
*possible* that it is something I've broken...


Thanks!


live well,
  vagrant
[signature.asc (application/pgp-signature, inline)]

Information forwarded to bug-guix <at> gnu.org:
bug#44626; Package guix. (Tue, 17 Nov 2020 14:31:02 GMT) Full text and rfc822 format available.

Message #16 received at 44626-done <at> debbugs.gnu.org (full text, mbox):

From: Ludovic Courtès <ludo <at> gnu.org>
To: Vagrant Cascadian <vagrant <at> debian.org>
Cc: 44626-done <at> debbugs.gnu.org
Subject: Re: bug#44626: tests/build-utils, tests/guix-system: fail when
 build path contains "~"
Date: Tue, 17 Nov 2020 15:29:55 +0100
Hi Vagrant,

Vagrant Cascadian <vagrant <at> debian.org> skribis:

> Though may introduce a different issue in tests/build-utils.log:
>
> ...
> test-name: wrap-script, simple case
> location: /build/guix-41NMGX/guix-1.2.0~rc1/tests/build-utils.scm:152
> source:
> + (test-equal
> +   "wrap-script, simple case"
> +   (string-append
> +     (format
> +       #f
> +       "#!~a --no-auto-compile\n#!#; Guix wrapper\n#\\-~s\n#\\-~s\n"
> +       (which "guile")
> +       '(begin
> +          (let ((current (getenv "GUIX_FOO")))
> +            (setenv
> +              "GUIX_FOO"
> +              (if current
> +                (string-append
> +                  "/some/path:/some/other/path"
> +                  ":"
> +                  current)
> +                "/some/path:/some/other/path"))))
> +       '(let ((cl (command-line)))
> +          (apply execl
> +                 "/anything/cabbage-bash-1.2.3/bin/sh"
> +                 (car cl)
> +                 (cons (car cl) (append '("") cl)))))
> +     script-contents)
> +   (call-with-temporary-directory
> +     (lambda (directory)
> +       (let ((script-file-name
> +               (string-append directory "/foo")))
> +         (call-with-output-file
> +           script-file-name
> +           (lambda (port) (display script-contents port)))
> +         (chmod script-file-name 511)
> +         (wrap-script
> +           script-file-name
> +           `("GUIX_FOO"
> +             prefix
> +             ("/some/path" "/some/other/path")))
> +         (let ((str (call-with-input-file
> +                      script-file-name
> +                      get-string-all)))
> +           (with-directory-excursion
> +             directory
> +             (delete-file "foo"))
> +           str)))))
> FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
>         destination: #<input-output:
>         /tmp/guix-directory.YrSRbV/foo.3efcPU 8>
>         format string: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
>         --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current
>         (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current
>         (string-append \"/some/path:/some/other/path\" \":\" current)
>         \"/some/path:/some/other/path\"))))\n#\\-(let ((cl
>         (command-line))) (apply execl
>         \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl)
>         (append (quote (\"\")) cl))))\n"
>         format args: ()
>         error args:  (#f "error in format" () #f)
> FORMAT: INTERNAL ERROR IN FORMAT-ERROR!
>         destination: #<input-output:
>         /tmp/guix-directory.YrSRbV/foo.3efcPU 8>
>         format string: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
>         --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current
>         (getenv \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current
>         (string-append \"/some/path:/some/other/path\" \":\" current)
>         \"/some/path:/some/other/path\"))))\n#\\-(let ((cl
>         (command-line))) (apply execl
>         \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car cl)
>         (append (quote (\"\")) cl))))\n"
>         format args: ()
>         error args:  (#<&wrap-error program:
>         "/tmp/guix-directory.YrSRbV/foo" type: misc-error>)
> expected-value: "#!/build/guix-41NMGX/guix-1.2.0~rc1/guile
> --no-auto-compile\n#!#; Guix wrapper\n#\\-(begin (let ((current (getenv
> \"GUIX_FOO\"))) (setenv \"GUIX_FOO\" (if current (string-append
> \"/some/path:/some/other/path\" \":\" current)
> \"/some/path:/some/other/path\"))))\n#\\-(let ((cl (command-line)))
> (apply execl \"/anything/cabbage-bash-1.2.3/bin/sh\" (car cl) (cons (car
> cl) (append (quote (\"\"))
> cl))))\n#!/anything/cabbage-bash-1.2.3/bin/sh\n\necho hello world"
> actual-value: #f
> actual-error:
> + (%exception
> +   #<&wrap-error program: "/tmp/guix-directory.YrSRbV/foo" type:
> misc-error>)
> result: FAIL

Turns out ‘wrap-script’ itself passes a non-literal string to ‘format’,
hence this error.  I’m fixing this in ‘core-updates’ since it’s a
full-rebuild change: commit 55fb5e5d2113a732a03e255371f0172800483023.

Thanks,
Ludo’.




bug archived. Request was from Debbugs Internal Request <help-debbugs <at> gnu.org> to internal_control <at> debbugs.gnu.org. (Wed, 16 Dec 2020 12:24:04 GMT) Full text and rfc822 format available.

This bug report was last modified 3 years and 152 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.