sbt / sbt-native-packager

sbt Native Packager
https://sbt-native-packager.readthedocs.io/en/stable/
BSD 2-Clause "Simplified" License
1.6k stars 441 forks source link

Scripts of main function and project level start up scripts overwrite each other #1397

Closed JakkuSakura closed 3 years ago

JakkuSakura commented 3 years ago

I have a project called test and the main function called Test::main()

Expected behaviour

sbt stage generates a script file called test for the project level start point and a script for each main function. At least it gives a warning for clashing names.

.
├── bin
│   ├── Test
│   ├── Test.bat
│   ├── test
│   └── test.bat
└── lib
    ├── default.test-0.1.jar
    └── org.scala-lang.scala-library-2.13.4.jar

Actual behaviour

sbt stage generates a single script file called test for either the project level start point or for the main function. If the project level start point overwrites the main function script, the main function fails to start. If the main function script overwrites the project level one, the whole project fails to start and an infinite recursion begins: shell level (1000) too high

.
├── bin
│   ├── test --- it calls itself infinitely or it executes java but no main class is passed
│   └── test.bat
└── lib
    ├── default.test-0.1.jar
    └── org.scala-lang.scala-library-2.13.4.jar

Information

Minimal Example Project

This project is the case that the project-level script overwrites the main function one. test.zip Changing the names of the project and main function plus other main functions may produce another case. Here's a minimal example pg-poller-test.zip file pg-poller which causes infinite recursion

#!/usr/bin/env bash

# Absolute path to this script
# macOS doesn't support "readlink -f"
realpath () {
  TARGET_FILE="$1"
  CHECK_CYGWIN="$2"

  cd "$(dirname "$TARGET_FILE")"
  TARGET_FILE=$(basename "$TARGET_FILE")

  COUNT=0
  while [ -L "$TARGET_FILE" -a $COUNT -lt 100 ]
  do
      TARGET_FILE=$(readlink "$TARGET_FILE")
      cd "$(dirname "$TARGET_FILE")"
      TARGET_FILE=$(basename "$TARGET_FILE")
      COUNT=$(($COUNT + 1))
  done

  if [ "$TARGET_FILE" == "." -o "$TARGET_FILE" == ".." ]; then
    cd "$TARGET_FILE"
    TARGET_FILEPATH=
  else
    TARGET_FILEPATH=/$TARGET_FILE
  fi

  # make sure we grab the actual windows path, instead of cygwin's path.
  if [[ "x$CHECK_CYGWIN" == "x" ]]; then
    echo "$(pwd -P)/$TARGET_FILE"
  else
    echo $(cygwinpath "$(pwd -P)/$TARGET_FILE")
  fi
}

# Uses uname to detect if we're in the odd cygwin environment.
is_cygwin() {
  local os=$(uname -s)
  case "$os" in
    CYGWIN*) return 0 ;;
    *)  return 1 ;;
  esac
}

# This can fix cygwin style /cygdrive paths so we get the
# windows style paths.
cygwinpath() {
  local file="$1"
  if is_cygwin; then
    echo $(cygpath -w $file)
  else
    echo $file
  fi
}

# get the absolute path for the current script
SCRIPT=$(realpath "$0")
SCRIPTPATH=$(dirname "$SCRIPT")

# execute the main start script
$SCRIPTPATH/pg-poller -main com.nadileaf.pg_poller.PgPoller "$@"
muuki88 commented 3 years ago

@qiujiangkun thanks for the detailed bug request. Would it be possible to provide the example projects as github repositories? This makes it easier to look at from my mobile devices and see what the issue is. :hugs:

IIRC we have some sort of heuristic to generate the name of the start script. Is there are hard requirement that you have the main entrypoints named all the same? IMHO unique names for your entrypoints solve this issue and make your colleagues happy as it's easier to find the right stuff :smile:

JakkuSakura commented 3 years ago

Sure, I have done it. https://github.com/qiujiangkun/bug-report-1 is the test, which turns out normal https://github.com/qiujiangkun/bug-report-2 is the pg-poller-test which is broken

I can work around the bug by renaming, after spending days on docker itself...

muuki88 commented 3 years ago

Okay, seeing the package names I guess the heuristic is tripping over the _ . The code is in the ScriptUtils.scala. I'm happy to merge a pull request that fixes this behaviour :heart:

You probably found [this documentation on script names|https://sbt-native-packager.readthedocs.io/en/latest/archetypes/java_app/index.html#a-note-on-script-names]