MisterDA / love-release

:love_letter: Lua script that makes LÖVE game release easier
MIT License
449 stars 27 forks source link

OSX getopt is different from linux's #24

Closed kikito closed 9 years ago

kikito commented 9 years ago

I have been trying to install this for a while but was not able to succeed. I would try to debug it myself, but my knowledge of bash and make is limited.

It does seem that gnu-getopt (or at least the version installed with brew install gnu-getopt) returns different output than the one installed in Linux.

When I execute getopt -T the only output I get in osx is two dashes ('--'). It seems that this output is not expected by this line, and it always fails. I have tried executing it with GETOPT_COMPATIBLE=, with similar results:

bash-4.3$ make
GNU getopt is not installed.
make: *** [deps] Error 1
bash-4.3$ GETOPT_COMPATIBLE= make
GNU getopt is not installed.
make: *** [deps] Error 1
bash-4.3$ GETOPT_COMPATIBLE=true make
GNU getopt is not installed.
make: *** [deps] Error 1
bash-4.3$
MisterDA commented 9 years ago

I think that your problem is simply that gnu-getopt has not overridden osx-getopt. There are some explanations in #22.

Try :

out=$(getopt -T)
if (( $? != 4 )) && [[ -n $out ]]; then
    echo "not GNU"
else
    echo "GNU"
fi

You may have recieved a message when you were installing, like this one (#22) :

This formula is keg-only, which means it was not symlinked into /usr/local.

OS X already provides this software and installing another version in parallel can cause all kinds of trouble.

At last there seems to be no problem with replacing OSX/BSD getopt by GNU getopt. If you are really afraid, you can:

If you want to double-check my code, this is the manual explaining everything :

-T, --test Test if your getopt(1) is this enhanced version or an old version. This generates no output, and sets the error status to 4. Other implementations of getopt(1), and this version if the environment variable GETOPT_COMPATIBLE is set, will return '--' and error status 0.

And my code snippet to detect the same thing :

    command -v getopt > /dev/null 2>&1 || {
        local opt=false
    } && {
        unset GETOPT_COMPATIBLE
        local out
        out=$(getopt -T)
        # error status != 4 and output is non-empty (ie = '--')
        if (( $? != 4 )) && [[ -n $out ]]; then
            local opt=false
        fi
    }
    if [[ $opt == false ]]; then
        >&2 echo "GNU getopt is not installed. Aborting."
        local EXIT=true
    fi
MisterDA commented 9 years ago

There was a small problem I discovered reading Google Shell style guide with local variables. It is related to your problem but it is not the direct cause, I think.

        local out=$(getopt -T)
        if (( $? != 4 )) && [[ -n $out ]]; then
            local opt=false
        fi

becomes this:

        local out
        out=$(getopt -T)
        # error status != 4 and output is non-empty (ie = '--')
        if (( $? != 4 )) && [[ -n $out ]]; then
            local opt=false
        fi

Have you succeeded installing and using love-release ?

kikito commented 9 years ago

Hi there,

In my case installing gnu-getopt with brew install gnu-getopt meant that it was not even installed in /usr/local/bin. Adding a link like that is called "symlinking" in homebrew. You can try to create the symlink:

$ brew link gnu-getopt
Warning: gnu-getopt is keg-only and must be linked with --force
Note that doing so can interfere with building software.

I don't want to do that with --force; can't risk my computer not building software correctly - I need it to earn my keep.

Gnu-getopt was available in the install dir, which happens to be /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt. I was able to run it from there.

I have tried making an alias to it at the top of love-release.sh:

#!/usr/bin/env bash

alias getopt='/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt'

Unfortunately the output is still the same, with or without GETOPT_COMPATIBLE=:

bash-4.3$ make
GNU getopt is not installed.
make: *** [deps] Error 1
bash-4.3$ GETOPT_COMPATIBLE= make
GNU getopt is not installed.
make: ***

May I suggest exploring other options instead of forcing the dependency on gnu-getopt? As it is, it seems more trouble than it's worth, at least in osx. If it's being used just so that there are long options (--author in addition to -a), I'd just stick with short options. Another one could be using something like this. But I have not tried that one.

Now that we are talking about this, why is bash 4 a dependency, too?

MisterDA commented 9 years ago

It's just that you had to add an alias in love-release.sh but also in the Makefile (cause it checks for dependencies too).

diff --git a/Makefile b/Makefile
index 491a074..206e26b 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,7 @@ deps:
        echo "unzip is not installed."; \
        EXIT=true; \
    }; \
+   alias getopt='/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt'; \
    command -v getopt > /dev/null 2>&1 || { \
        opt=false; \
    } && { \
diff --git a/love-release.sh b/love-release.sh
index 317a39c..782c43d 100755
--- a/love-release.sh
+++ b/love-release.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash

+alias getopt='/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt'
+
 # LÖVE version
 readonly LOVE_DEF_VERSION=0.9.2

I will manage to make love-release use GNU getopt, fallback to getopts_long or simply use short options.

About bash... come on ! it's been around since 2009 ! I just didn't take the time to see which features were introduced in bash 4 and if it could cause incompatibilities... but I think I just use a very specific case of parameter expansion... converting from uppercase to lowercase. That can easily be replaced with a tr '[[:upper:]]' '[[:lower:]]'.

MisterDA commented 9 years ago

f*ck it I'll just learn Python and rewrite it

kikito commented 9 years ago

Sorry but no dice:

bash-4.3$ make
GNU getopt is not installed.
make: *** [deps] Error 1

bash-4.3$ GETOPT_COMPATIBLE= make
GNU getopt is not installed.
make: *** [deps] Error 1

bash-4.3$ /usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt -V
getopt (enhanced) 1.1.6

bash-4.3$ git diff
diff --git a/Makefile b/Makefile
index 491a074..206e26b 100644
--- a/Makefile
+++ b/Makefile
@@ -79,6 +79,7 @@ deps:
                echo "unzip is not installed."; \
                EXIT=true; \
        }; \
+       alias getopt='/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt'; \
        command -v getopt > /dev/null 2>&1 || { \
                opt=false; \
        } && { \
diff --git a/love-release.sh b/love-release.sh
index 317a39c..782c43d 100755
--- a/love-release.sh
+++ b/love-release.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash

+alias getopt='/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt'
+
 # LÖVE version
 readonly LOVE_DEF_VERSION=0.9.2

About bash... come on ! it's been around since 2009 !

I don't doubt that- but still, my OSX had 3.x. I had to update. It's just yet another pebble in the way.

f*ck it I'll just learn Python and rewrite it

That would be a bit crazy, wouldn't it? xD

If you are considering the rewrite path, may I suggest doing it in Lua? If you do a luarock then people should be able to install it with luarock install love-release. You could even use rocks for the zip & curl stuff, and specify them as dependencies, so the installation was dependency-free. After a quick look, it seems you would need luafilesystem + luacurl + lua-zlib (or some other zip lib)

MisterDA commented 9 years ago

Yes that could be nice, but doesn't luarock only provide lua libraries ? love-release is an executable, a command, not a lib. How could I use advantage of love-release ?

kikito commented 9 years ago

Not at all, you can create executables as well!

Here's an example: the telescope luarock provides an executable called tsc. It does so by doing two things:

MisterDA commented 9 years ago

Hi ! I have began to rewrite love-release, you can check the luarocks branch :) And you can install it with luarocks too !

luarocks install --server=http://luarocks.org/dev love-release

But don't forget to check the troubleshooting section, there are some bugs with the zip library I use. Thanks for the help !

kikito commented 9 years ago

^O^ cool!