[PATCH] makepkg: allow the use of only a package() function

View: New views
7 Messages — Rating Filter:   Alert me  

[PATCH] makepkg: allow the use of only a package() function

by Cedric Staniewski :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

For some packages, generally the 'any' arch ones, a build step is not
required and therefore can be skipped. In these cases, a package()
function without a build() one is sufficient.

As a side effect, this commit makes meta packages without any function
at all in the PKGBUILD possible.

Fixes FS#15147.

Signed-off-by: Cedric Staniewski <cedric@...>
---
 doc/PKGBUILD.5.txt    |   12 ++++++------
 scripts/makepkg.sh.in |   17 +++++++++++++----
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/doc/PKGBUILD.5.txt b/doc/PKGBUILD.5.txt
index 28dd8c7..2d6589b 100644
--- a/doc/PKGBUILD.5.txt
+++ b/doc/PKGBUILD.5.txt
@@ -233,10 +233,10 @@ name. The syntax is: `source=('filename::url')`.
 
 build() Function
 ----------------
-In addition to the above directives, the build() bash function comprises the
-remainder of the PKGBUILD. This is directly sourced and executed by makepkg, so
-anything that bash or the system has available is available for use here. Be
-sure any exotic commands used are covered by `makedepends`.
+In addition to the above directives, the optional build() bash function usually
+comprises the remainder of the PKGBUILD. This is directly sourced and executed by
+makepkg, so anything that bash or the system has available is available for use
+here. Be sure any exotic commands used are covered by `makedepends`.
 
 All of the above variables such as `pkgname` and `pkgver` are available for use
 in the build function. In addition, makepkg defines three variables for your
@@ -263,8 +263,8 @@ package() Function
 An optional package() function can be specified in addition to the build() function.
 This function is run immediately after the build() function. When specified in
 combination with the fakeroot BUILDENV option in linkman:makepkg.conf[5], fakeroot
-usage will be limited to running the packaging stage. The build() function will be
-run as the user calling makepkg.
+usage will be limited to running the packaging stage. An existing build() function
+will be run as the user calling makepkg.
 
 Package Splitting
 -----------------
diff --git a/scripts/makepkg.sh.in b/scripts/makepkg.sh.in
index a6780d7..2b540b4 100644
--- a/scripts/makepkg.sh.in
+++ b/scripts/makepkg.sh.in
@@ -72,6 +72,7 @@ LOGGING=0
 SOURCEONLY=0
 IGNOREARCH=0
 HOLDVER=0
+BUILDFUNC=0
 PKGFUNC=0
 SPLITPKG=0
 PKGLIST=""
@@ -140,7 +141,9 @@ clean_up() {
  rm -rf "$pkgdir" "$srcdir"
  if [ -n "$pkgbase" ]; then
  # Can't do this unless the BUILDSCRIPT has been sourced.
- rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"*
+ if (( BUILDFUNC )); then
+ rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-build.log"*
+ fi
  if [ "$PKGFUNC" -eq 1 ]; then
  rm -f "${pkgbase}-${pkgver}-${pkgrel}-${CARCH}-package.log"*
  elif [ "$SPLITPKG" -eq 1 ]; then
@@ -1754,6 +1757,12 @@ if [ "${#pkgname[@]}" -gt "1" ]; then
  SPLITPKG=1
 fi
 
+# test for available PKGBUILD functions
+# The exclamation mark is required here to avoid triggering the ERR trap when
+# a tested function does not exist.
+if [[ $(! type -t build) = "function" ]]; then
+ BUILDFUNC=1
+fi
 if [ "$(type -t package)" = "function" ]; then
  PKGFUNC=1
 elif [ $SPLITPKG -eq 0 -a "$(type -t package_${pkgname})" = "function" ]; then
@@ -1814,7 +1823,7 @@ fi
 if [ "$INFAKEROOT" -eq 1 ]; then
  if [ "$SPLITPKG" -eq 0 ]; then
  if [ "$PKGFUNC" -eq 0 ]; then
- if [ "$REPKG" -eq 0 ]; then
+ if (( BUILDFUNC && ! REPKG )); then
  run_build
  tidy_install
  fi
@@ -1928,7 +1937,7 @@ else
  if [ "$(check_buildenv fakeroot)" != "y" -o $EUID -eq 0 ]; then
  if [ "$REPKG" -eq 0 ]; then
  devel_update
- run_build
+ (( BUILDFUNC )) && run_build
  fi
  if [ "$SPLITPKG" -eq 0 ]; then
  if [ "$PKGFUNC" -eq 1 ]; then
@@ -1953,7 +1962,7 @@ else
  else
  if [ "$REPKG" -eq 0 -a \( "$PKGFUNC" -eq 1 -o "$SPLITPKG" -eq 1 \) ]; then
  devel_update
- run_build
+ (( BUILDFUNC )) && run_build
  cd "$startdir"
  fi
 
--
1.6.5.2



Re: [PATCH] makepkg: allow the use of only a package() function

by Allan McRae-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Cedric Staniewski wrote:

> For some packages, generally the 'any' arch ones, a build step is not
> required and therefore can be skipped. In these cases, a package()
> function without a build() one is sufficient.
>
> As a side effect, this commit makes meta packages without any function
> at all in the PKGBUILD possible.
>
> Fixes FS#15147.
>
> Signed-off-by: Cedric Staniewski <cedric@...>
> ---
> <snip>
>  
>  
> +# test for available PKGBUILD functions
> +# The exclamation mark is required here to avoid triggering the ERR trap when
> +# a tested function does not exist.
> +if [[ $(! type -t build) = "function" ]]; then
> + BUILDFUNC=1
> +fi
>  

This certainly appears to work, but can you explain how?  Here is my
understanding.  The "!" means that when build() is not present, the
function will still return 0 (not triggering the err trap) and the
comparison then fails.   When build() function is present, the type
-t... outputs "function" but returns 1.  How is the err trap not  set of
then?  Is it because there is a value output?

Anyway, this is certainly a good catch for when applying the [[ & ((
patch.   The rest of the patch looks good to me.

Allan


Re: [PATCH] makepkg: allow the use of only a package() function

by Cedric Staniewski :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Allan McRae wrote:

> Cedric Staniewski wrote:
>> For some packages, generally the 'any' arch ones, a build step is not
>> required and therefore can be skipped. In these cases, a package()
>> function without a build() one is sufficient.
>>
>> As a side effect, this commit makes meta packages without any function
>> at all in the PKGBUILD possible.
>>
>> Fixes FS#15147.
>>
>> Signed-off-by: Cedric Staniewski <cedric@...>
>> ---
>> <snip>
>>    
>> +# test for available PKGBUILD functions
>> +# The exclamation mark is required here to avoid triggering the ERR
>> trap when
>> +# a tested function does not exist.
>> +if [[ $(! type -t build) = "function" ]]; then
>> +    BUILDFUNC=1
>> +fi
>>  
>
> This certainly appears to work, but can you explain how?  Here is my
> understanding.  The "!" means that when build() is not present, the
> function will still return 0 (not triggering the err trap) and the
> comparison then fails.   When build() function is present, the type
> -t... outputs "function" but returns 1.  How is the err trap not  set of
> then?  Is it because there is a value output?

There is no real explanation, only "that's how it works in bash". ;)
>From bash's manpage:

> trap [-lp] [[arg] sigspec ...]
> [...]
> The ERR trap is not executed if the failed command is part of the command
> list immediately following a while or until keyword, part of the test in
> an if statement, part of a command executed in a &&  or  || list,  or if
> the command's return value is being inverted via !.

Note that apparently only the test/[ builtin is meant here.

Your explanation is correct for return codes, but it is not applicable here, because the ERR signal is not the same as a return code greater than zero.

Given this script:
-----------------
#!/bin/bash
set -E
trap 'echo >&2 "error"' ERR

echo test1
type -t package
echo ret: $?
echo

echo test2
! type -t package
echo ret: $?
echo

echo test3
type -t package || echo 1
echo ret: $?
echo

echo test4
type -t package && echo 1
echo ret: $?
echo
-----------------

It will generate the following output.

> $ ./test.sh
> test1
> error
> ret: 1
>
> test2
> ret: 0
>
> test3
> 1
> ret: 0
>
> test4
> ret: 1

The interesting case is the last one. "type -t package" returns the return code 1 and an ERR signal, but the ERR trap is not triggered, even though "echo 1" is actually never executed. So, there are several possibilities to catch the ERR signal and I only went for the exclamation mark, because it is the shortest one :). It would also be possible to use "|| echo" if you think it is easier to understand, however, it implies a wrong assumption (return code > 0 = ERR) in my opinion and the "echo" is not needed here.

>
> Anyway, this is certainly a good catch for when applying the [[ & ((
> patch.   The rest of the patch looks good to me.

I thought I already comment about this in the thread. Anyway, you are aware of it now.

>
> Allan



Re: [PATCH] makepkg: allow the use of only a package() function

by Isaac Good-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Nov 01, 2009 at 05:45:27PM +0000, Cedric Staniewski wrote:

> Allan McRae wrote:
> >From bash's manpage:
>
> > trap [-lp] [[arg] sigspec ...]
> > [...]
> > The ERR trap is not executed if the failed command is part of the command
> > list immediately following a while or until keyword, part of the test in
> > an if statement, part of a command executed in a &&  or  || list,  or if
> > the command's return value is being inverted via !.
>
> Note that apparently only the test/[ builtin is meant here.
>

I get the same results with both test/[ as with [[

Reusing your code,

> set -E
> trap 'echo >&2 "error"' ERR
>
> false
> [ false ]
> [[ false ]]
> (( 0 ))
> ! true

Only the 'false' by itself triggers the trap. [ and [[ and treated the same.


Re: [PATCH] makepkg: allow the use of only a package() function

by Cedric Staniewski :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Isaac Good wrote:

> On Sun, Nov 01, 2009 at 05:45:27PM +0000, Cedric Staniewski wrote:
>> Allan McRae wrote:
>> >From bash's manpage:
>>
>>> trap [-lp] [[arg] sigspec ...]
>>> [...]
>>> The ERR trap is not executed if the failed command is part of the command
>>> list immediately following a while or until keyword, part of the test in
>>> an if statement, part of a command executed in a &&  or  || list,  or if
>>> the command's return value is being inverted via !.
>> Note that apparently only the test/[ builtin is meant here.
>>
>
> I get the same results with both test/[ as with [[
>
> Reusing your code,
>
>> set -E
>> trap 'echo >&2 "error"' ERR
>>
>> false
>> [ false ]
>> [[ false ]]
>> (( 0 ))
>> ! true
>
> Only the 'false' by itself triggers the trap. [ and [[ and treated the same.


You missed a small, but important part of the sentence:

> part of the test *in an if statement*

Consequently, this script
--------------------
#!/bin/bash
set -E
trap 'echo >&2 "error"' ERR

echo test1
if test $(type -t package); then
        echo 1
fi

echo test2
if [ $(type -t package) ]; then
        echo 1
fi

echo test3
if [[ $(type -t package) ]]; then
        echo 1
fi

echo test4
if (( $(type -t package) )); then
        echo 1
fi
--------------------

results in

$ ./test.sh
test1
test2
test3
error
test4
error


Re: [PATCH] makepkg: allow the use of only a package() function

by Allan McRae-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Cedric Staniewski wrote:

> Isaac Good wrote:
>  
>> On Sun, Nov 01, 2009 at 05:45:27PM +0000, Cedric Staniewski wrote:
>>    
>>> Allan McRae wrote:
>>> >From bash's manpage:
>>>
>>>      
>>>> trap [-lp] [[arg] sigspec ...]
>>>> [...]
>>>> The ERR trap is not executed if the failed command is part of the command
>>>> list immediately following a while or until keyword, part of the test in
>>>> an if statement, part of a command executed in a &&  or  || list,  or if
>>>> the command's return value is being inverted via !.
>>>>        
>>> Note that apparently only the test/[ builtin is meant here.
>>>
>>>      
>> I get the same results with both test/[ as with [[
>>
>> Reusing your code,
>>
>>    
>>> set -E
>>> trap 'echo >&2 "error"' ERR
>>>
>>> false
>>> [ false ]
>>> [[ false ]]
>>> (( 0 ))
>>> ! true
>>>      
>> Only the 'false' by itself triggers the trap. [ and [[ and treated the same.
>>    
>
>
> You missed a small, but important part of the sentence:
>
>  
>> part of the test *in an if statement*
>>    
>
> Consequently, this script
> --------------------
> #!/bin/bash
> set -E
> trap 'echo >&2 "error"' ERR
>
> echo test1
> if test $(type -t package); then
> echo 1
> fi
>
> echo test2
> if [ $(type -t package) ]; then
> echo 1
> fi
>
> echo test3
> if [[ $(type -t package) ]]; then
> echo 1
> fi
>
> echo test4
> if (( $(type -t package) )); then
> echo 1
> fi
> --------------------
>
> results in
>
> $ ./test.sh
> test1
> test2
> test3
> error
> test4
> error
>  

Thanks for the explanation.  This all makes perfect sense to me now.  
Patch is push to my working branch.

Allan




Re: [PATCH] makepkg: allow the use of only a package() function

by Isaac Good-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Nov 01, 2009 at 07:29:20PM +0000, Cedric Staniewski wrote:

> Isaac Good wrote:
> > On Sun, Nov 01, 2009 at 05:45:27PM +0000, Cedric Staniewski wrote:
> >> Allan McRae wrote:
> >> >From bash's manpage:
> >>
> >>> trap [-lp] [[arg] sigspec ...]
> >>> [...]
> >>> The ERR trap is not executed if the failed command is part of the command
> >>> list immediately following a while or until keyword, part of the test in
> >>> an if statement, part of a command executed in a &&  or  || list,  or if
> >>> the command's return value is being inverted via !.
> >> Note that apparently only the test/[ builtin is meant here.
> >>
> >
> > I get the same results with both test/[ as with [[
> >
> > Reusing your code,
> >
> >> set -E
> >> trap 'echo >&2 "error"' ERR
> >>
> >> false
> >> [ false ]
> >> [[ false ]]
> >> (( 0 ))
> >> ! true
> >
> > Only the 'false' by itself triggers the trap. [ and [[ and treated the same.
>
>
> You missed a small, but important part of the sentence:
>
> > part of the test *in an if statement*
>
> Consequently, this script
> --------------------
> #!/bin/bash
> set -E
> trap 'echo >&2 "error"' ERR
>
> echo test1
> if test $(type -t package); then
> echo 1
> fi
>
> echo test2
> if [ $(type -t package) ]; then
> echo 1
> fi
>
> echo test3
> if [[ $(type -t package) ]]; then
> echo 1
> fi
>
> echo test4
> if (( $(type -t package) )); then
> echo 1
> fi
> --------------------
>
> results in
>
> $ ./test.sh
> test1
> test2
> test3
> error
> test4
> error
>
 
I brought this up in FreeNode/#bash and at the very least there is an error in the man pages. More likely a bug in [[. This should be reported upstream to Chet (bash).
 - Isaac