ide icon indicating copy to clipboard operation
ide copied to clipboard

devon ide uninstall does not remove devon from cygwin

Open hohwille opened this issue 5 years ago • 18 comments

On Windows:

  1. ensure you have cygwin installed
  2. install devon-ide (download, extract, run setup.bat)
  3. uninstall devon-ide (devon ide uninstall)
  4. open cygwin terminal:
-bash: /home/hohwille/.devon/devon: No such file or directory

This is because /home/hohwille/.bashrc is still containing the devon alias and call.

hohwille avatar Aug 30 '19 14:08 hohwille

Hi, I am currently looking into issue 243. I did exactly as you described. Executed the setup.bat, executed ‘devon’ and the file .bashrc contained:

alias devon="source ~/.devon/devon" devon

Then I executed ‘devon ide uninstall’ and the file .bashrc was empty again. No alias for me. It seems I do miss the point. Could you explain to me a bit more detailed what is supposed to happen or where do I have to look for the bug?

dhelmke avatar Sep 09 '19 13:09 dhelmke

I have not verified this yet, but seems be worth a comment here:

Currently devon.bat tries to locate cygwin's bash, sets a $HOME variable - using default cygwin conventions - and then calls bash with the devon scriptlet as command. But when cygwin-bash is called interactively, some more profile initialization files are read - on system and/or on user level. And those may set a different $HOME !

So it might be more stable, if devon.bat starts the located bash with an additional "--login" option, so it reads the same set of initialization files as during later interactive usage. I would also remove the set of a an explicit HOME variable in the cygwin case.

Same may be true for the MSYS2 / git-for-windows bash, but I have not checked either in detail.

markusschuh avatar Sep 10 '19 12:09 markusschuh

After testing a bit it seems that the ${USER} variable in the function doUnistall in the ide commandlet is not defined for me.

if [ -d "/c/cygwin64" ] then echo uservariable ${USER} doUninstallFromHome "/c/cygwin64/home/${USER}"

That prevents removing the part from the .bashrc in /c/cygwin64/home//.bashrc , because the ${USER} is missing. That seems at least for me to be the error here.

dhelmke avatar Sep 12 '19 08:09 dhelmke

Replacing it with ${USERNAME} seems to work for me.

dhelmke avatar Sep 12 '19 08:09 dhelmke

But i still got the error when executing setup.bat:

/cygdrive/c/Users/dhelmke/.bashrc: line 21: devon: command not found

dhelmke avatar Sep 12 '19 08:09 dhelmke

I can just give some background info about - potentially - origin of environment variables:

  • USERNAME: This is defined by Windows. If cygwin is started, it will be incorporated from the starting process (a Windows process) and also be available in a cygwin - or git - bash. Of course every sub process is allowed to also remove environment variables inherited from parent ....

  • USER: Typically set from login initialization files - sometimes also during standard bash initialization shell scripts. Also is inherited to interactively started shell scripts from the parent - the login shell.

A recent cygwin installation should have

USER="$(/usr/bin/id -un)"
...
export .... USER

inside /etc/profile Hence cygwin bash should see the $USER when started with the --login argument.

Use of $USERNAME may potentially not work that good outside of windows.

All that background does not explain, why the "devon command not found" issue has appeared at all. Sorry.

markusschuh avatar Sep 12 '19 15:09 markusschuh

Thank you for your input Markus. The bash is already executed with the -l parameter. Regarding the USERNAME variable, it is only used if Windows is the OS. Can that be a problem?

My best guess at the moment is that a control character inside the .bashrc file is the reason for the error message. Is that possible? I know far to less of the bash topic to be sure about it. Best Regards Daniel

dhelmke avatar Sep 12 '19 21:09 dhelmke

By changing the setup in the devon file to:

if [ ! -f ~/.devon/devon ] then mkdir -p ~/.devon
echo "Copying devon CLI script to your home directory..." cp "${BASH_SOURCE:-$0}" ~/.devon/devon if [ ! -e ~/.bashrc ] then touch ~/.bashrc fi if ! grep -q "alias devon=" ~/.bashrc then echo "Installing devon alias to your .bashrc" #echo -e '\nalias devon="source ~/.devon/devon"\ndevon' >> ~/.bashrc echo -e '\nalias devon="source ~/.devon/devon"devon' >> ~/.bashrc fi

means removing the \n before the last devon and deleting the .bashrc file in

/cygdrive/c/Users/dhelmke

the error message vanished when executing setup.bat again. I do not know, if that could be a solution?

dhelmke avatar Sep 12 '19 22:09 dhelmke

Thanks for all your investigations so far. I want to shed a light in why the problem occurred for me:

  • The devon-ide installs devon bash script into ~/.devon/devon, where in windows ~ here always is the windows home directory of the user (`%USERPROFILE%).
  • mingw/msys is using the same home directory hence the alias and initial invocation is in the .bashrc in that same home directory
  • if additionally cygwin is installed, this has its own HOME directory. This is a philosophy of cygwin that we may not like (I do not like it) but that we IMHO should not change as we might break other things if we work against cygwin.
  • However, this results in a second .bashrc on the same machine for cygwin. Now if devon-ide is uninstalled, it has to remove ~/.devon/devon as well as the alias from .bashrc (and .zshrc) from both windows user home as well as cygwin-home.
  • As the removal from cygwin-home is not working properly the alias remains in that .bashrc.
  • Then if someone starts a cygwin terminal that .bashrc is executed and obviously produces the error message stated in this issue at the top as the devon bash script has already been deleted.

Hence the only remaining question is IMHO how can we reliably determine the users CYGWIN home directory if we are in windows. Then we could actually do both the installation (setup) as well as the uninstall from the ide commandlet:

if doIsWindows
then
  CYGWIN_HOME="$(magic_command)"
  if [ -d "${CYGWIN_HOME}" ]
  then
    // doInstallToHome "${CYGWIN_HOME}"
    doUninstallFromHome "${CYGWIN_HOME}"
  fi
fi

hohwille avatar Sep 13 '19 06:09 hohwille

I do not fully agree on this, since for me the main question is: "Why should a single install / uninstall try to support different runtime environments on the same machine at the same time at all?"

If the devon.bat would use the --login option for all (or potentially all) %BASH% calls, every bash script should just use whatever $HOME is valid for it's own runtime environment. That should be true for both doInstallToHome as well as doUnInstallToHome

Sure - if the user changes the configuration for $HOME in a runtime environment between devon install and uninstall, adds/remove such a runtime enviroment, more corner cases may exist. Inventing some $(magic_command), which tries to control all possible different $HOME in different runtime environments from only one runtime will also fail in such corner cases, I guess.

markusschuh avatar Sep 13 '19 07:09 markusschuh

Executing

doUninstallFromHome "/cygdrive/c/home/Users/${USERNAME}"

removed devon from the .bashrc file, but that is kind of hard coding I guess. Or is cygdrive always installed this way on Windows?

dhelmke avatar Sep 13 '19 09:09 dhelmke

By changing the line in the ide commandlet:

if [ -d "/c/cygwin64" ]

to:

if [ -d $(cygpath "${CYGWIN_HOME}") ]

there would be less hard coding.

And then executing:

doUninstallFromHome "$(cygpath "${CYGWIN_HOME}")/home/${USERNAME}" doUninstallFromHome "/cygdrive$(cygpath "${SYSTEMDRIVE}")/home/Users/${USERNAME}"

will remove the devon entries from all files. /cygdrive is a kind of prefix used by cygwin, so there seems to be no variable for that. The part with /home/Users seems to be the same in every cygwin installation. The Variable USERNAME is only used, when the OS is Windows, so that should work as well. Together with removing the /n as mentioned above on my system the error message when executing setup.bat is gone and devon is completely uninstalled from cygwin after executing devon ide uninstall.

The only %BASH% call I found is in the setup.bat and it uses the –login option. But I may miss here something.

dhelmke avatar Sep 25 '19 11:09 dhelmke

The devon.bat calls

 "%BASH%" -c 'source ~/.devon/devon %*'

so a

devon ide uninstall

that has not identified an installed git-bash (highest prio) and afterwards successfully locates a cygwin bash, will start this cygwin bash without --login - which leaves the "whatever in cygwin configured $HOME" undefined, so devon (now the bash code) defines the HOME based on own guessing.

I assume, in the majority of cases this guessing is correct. But using the --login here looks more correct to me.

With respect to your proposal to introduce $(cygpath "${CYGWIN_HOME}"): Please have another look on the context - this is used within the else clause of the [ "${OSTYPE}" = "cygwin" ] check. I doubt, a ${CYGWIN_HOME} is defined outside of cygwin itself.

Anyway my intention is more to make the logic more simpler, instead of trying to support any whatsoever configured special case. My statement is, that the devon ide install and uninstall should never try to write from git-bash to cygwin environment - or vice versa.

This can of course also lead into a system with remaining artifacts of some devon ide components after some ide uninstall when during install and uninstall the user has changed his decision about what environment - either git bash or cygwin - he wants to use. But this is quite a corner case - which will IMHO never be fully free of issues.

May be it is best to just close this issue with won't fix?

markusschuh avatar Sep 25 '19 12:09 markusschuh

Hi Markus,

Thank you for your input, I must have missed the bash call in the devon.bat, sorry for that.

The

if [ "${OSTYPE}" = "cygwin" ]

was always false on my pc, because the OS was never recognized as cygwin, so when I put my code in the else clause, it worked as expected. I would not mind to close the issue, because I don’t know how to fix the issue otherwise, but that’s not on me to decide.

dhelmke avatar Sep 25 '19 13:09 dhelmke

OSTYPE is set by the bash binary - see man bash - and the original definition for its value is at http://git.savannah.gnu.org/cgit/automake.git/tree/lib/config.sub (used by at least most GNU tools - like bash)

So in case you have really started a cygwin bash, the condition should result in true. It is quite confusing that POSIX sh (and bash) support both "=" and "==" as string compare operand - but the condition is correct and must match for cygwin-bash.

I can just imagine, that some older - or 32bit? - setups of cygwin might have something added to the end of cygwin - this is in compliance to the definition by GNU above, which lists cygwin*, not cygwin.

So it might be better to rewrite this code (and the other usage of OSTYPE) with case - which offers "globbing" and is the most compatible approach to this.

case "$OSTYPE" in
  cygwin*)   
        # code for cygwin
        ;;
  *)     
        # code for else   
        ;;
esac

If " if [[ ... ]]" were used, it's even easy with if, but this isn't POSIX syntax.

Nevertheless, cygwin is a dying out solution - but quite slowly, though ...

markusschuh avatar Sep 25 '19 15:09 markusschuh

Hi Markus,

Thank you for your input again. Until now I was just looking at the situation, when someone used the devon cmd shell. So the ${OSTYPE} was never cygwin. If someone is using the cygwin bash to install and uninstall, the commands could look like:

if doIsWindows
 then
   if [ "${OSTYPE}" = "cygwin" ]
   then
	 doUninstallFromHome "$(cygpath "${SYSTEMDRIVE}")/home/Users/${USER}"
	 doUninstallFromHome " $(cygpath "${SYSTEMDRIVE}")${HOME}"
   else
	if [ -d $(cygpath "${CYGWIN_HOME}") ]
       then
         doUninstallFromHome "/cygdrive$(cygpath"${SYSTEMDRIVE}")/home/Users/${USERNAME}"
         doUninstallFromHome "$(cygpath "${CYGWIN_HOME}")/home/${USERNAME}"

With these lines the installation and uninstallation should work. It could as well use case.

dhelmke avatar Sep 26 '19 04:09 dhelmke

But further testing by using a new devon cmd shell to uninstall devon proofed that ${CYGWIN_HOME} Variable is not longer defined. So the code would need another hardcoding again like:

if doIsWindows
  then
    if [ "${OSTYPE}" = "cygwin" ]
    then
	doUninstallFromHome "$(cygpath "${SYSTEMDRIVE}")/home/Users/${USER}"
	doUninstallFromHome " $(cygpath "${SYSTEMDRIVE}")${HOME}"
    else
	if [ -d "$(cygpath "${SYSTEMDRIVE}")/cygwin64" ]
      then
        doUninstallFromHome "/cygdrive$(cygpath"${SYSTEMDRIVE}")/home/Users/${USERNAME}"
        doUninstallFromHome "$(cygpath "${SYSTEMDRIVE}")/cygwin64/home/${USERNAME}"
      elif [ -d "$(cygpath "${SYSTEMDRIVE}")/cygwin" ]
      then
        doUninstallFromHome "/cygdrive$(cygpath"${SYSTEMDRIVE}")/home/Users/${USERNAME}"
        doUninstallFromHome "$(cygpath "${SYSTEMDRIVE}")/cygwin/home/${USERNAME}"

That does not look much better than the code is now I guess.

dhelmke avatar Sep 26 '19 05:09 dhelmke

I don't understand, what you want to achieve here. Also I have the feeling, that you have some mix ups in your code, e.g. use of /cygdrive when $OSTYPE is not cygwin A user can use any mount prefix he wants, but I doubt, anybody uses /cygdrive other than in the case, where it is chosen by default during setup. In other environments, the mount prefix for the Windows drives is either /mnt or just /.

My proposal for the moment were to just resolve here, what was originally described as issue:

-bash: /home/hohwille/.devon/devon: No such file or directory

The simplest approach to avoid such messages is to just change the current unconditional devoncall inside .bashrc / .zshrcinto a conditional one:

test -x $HOME/.devon/devon && $HOME/.devon/devon

That way, the script execution is only tried, when script exists and is executable. If script does not exist, nothing is executed - and there isn't an error message. => Issue solved

markusschuh avatar Sep 30 '19 15:09 markusschuh