Skip to content
Permalink
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Go to file
 
 
Cannot retrieve contributors at this time
executable file 482 lines (388 sloc) 19.3 KB
#! /usr/bin/bash
# ------------------------------------------------------------------- Debug
# COOKIE=$(mcookie|cut -c-8); grep -v V_GREP_ME $0 > /dev/shm/runme-$COOKIE.sh ; sleep 0.3; exec bash /dev/shm/runme-$COOKIE.sh
# TESTING=1
# ---------------------------------------------------------------- Preamble
PKG=fragpipe
VERSION=22.0
BUILD=0
# some pipeline parts need python
PYTHONVER=3.11.11
set -e
umask 022
PATH=/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/package/bin
PREFIX=/pkg/$PKG-$VERSION-$BUILD
if [ -n "$TESTING" ]; then PREFIX=/scratch/local2/$PKG-$VERSION-$BUILD ; fi
mkdir -p $PREFIX
cat >$PREFIX/profile <<-EOF
. /pkg/openjdk-21.0.0.35-0/profile
PATH=$PREFIX/bin:\$PATH
# avoid interference with the package/pkg python
if [ -z "\$PYTHONUSERBASE" ]; then export PYTHONUSERBASE=\$HOME/.local/fragpipe-python ; fi
if [ -d $PREFIX/.compatlibs ]; then export LD_LIBRARY_PATH=$PREFIX/.compatlibs\${LD_LIBRARY_PATH:+:}\$LD_LIBRARY_PATH ; fi
EOF
source $PREFIX/profile
BUILD_TMPDIR=/scratch/local2/$PKG-$VERSION-$BUILD.$USER.build.tmp
# keep pip's download cache when testing
test -z "$TESTING" && test -d $BUILD_TMPDIR && ( chmod -R u+rwx $BUILD_TMPDIR || true ; rm -rf $BUILD_TMPDIR )
mkdir -p $BUILD_TMPDIR/home
# embedded patches, copy script to an accessible location
cp $0 $BUILD_TMPDIR; ME="$BUILD_TMPDIR/$(basename $0)"
export TMPDIR=$BUILD_TMPDIR
export HOME=$BUILD_TMPDIR/home
NPROC=$(( $(nproc) * 4 / 5 + 1 ))
BUILDDIR=$PREFIX/build
mkdir -p $BUILDDIR
cd $BUILDDIR
# ---------------------------------------------------------------- fragpipe
# the complete installable archive, but permissions are a mess!
# orig: https://github.com/Nesvilab/FragPipe/releases/download/22.0/FragPipe-22.0.zip
BEEHIVE=https://beehive.molgen.mpg.de/e30d93e6c0ef1e2aadd51e732f343451/FragPipe-22.0.zip
test -e FragPipe-$VERSION.zip || wget -nv $BEEHIVE
test -d fragpipe || bsdtar -xf FragPipe-$VERSION.zip
mv fragpipe/bin ..
mv fragpipe/lib .. # 'libjava' would be smart, but fp uses lib in lookup routines :/
mv fragpipe/tools ..
mv fragpipe/workflows ../workflows_dist
# reset executable attribute in the obvious cases, nerve ...
# some *.py have a shebang, and some ... (you guessed)
# this is safer then accidentally 'defusing' linux binaries within tools
for ext in bat dll exe ico jar obo txt tsv ifl gdb pdb xml json glyc fasta workflow params; do
find $PREFIX -type f -name "*.$ext" -exec chmod -c 0644 {} \+
done
find $PREFIX -type d -exec chmod -c 0755 {} \+
# set jar mtimes according to content (btw. I didn't know that java was already around in 1980 :)
rm -vf jarredater
sed -ne '/^#Epatch:jarredater/ s/^#Epatch:\S* // p' $ME | patch -p0 --verbose
find $PREFIX -name '*.jar' -exec python jarredater {} \+
(
# get rid of the way distracting console warning "No interface org.openide.util.spi.SVGLoader instance found"
cd ../lib
mkdir -p fixup
cd fixup
bsdtar -xf ../org-netbeans-swing-outline-RELEASE200.jar
rm -v ./org/netbeans/swing/etable/columns.svg # the root cause
jar -M -c -f org-netbeans-swing-outline-RELEASE200.jar META-INF org
# alternative ...
# mv META-INF/MANIFEST.MF .
# jar -c -f org-netbeans-swing-outline-RELEASE200.jar -m MANIFEST.MF META-INF org
mv -v org-netbeans-swing-outline-RELEASE200.jar ..
cd ..
rm -r fixup
)
# the source archive , some bigger libs missing (diann torch_cpu), permissions here are again messed up
# 'FragPipe-22.0.tar.gz' -> '/src/mariux/md5repo/bfaae508143e0a67b28a6393cbb7b2fb/FragPipe-22.0.tar.gz'
# orig: https://github.com/Nesvilab/FragPipe/archive/refs/tags/22.0.tar.gz
BEEHIVE=https://beehive.molgen.mpg.de/bfaae508143e0a67b28a6393cbb7b2fb/FragPipe-22.0.tar.gz
test -e FragPipe-$VERSION.tar.gz || wget -nv $BEEHIVE
test -d FragPipe-$VERSION || tar -xf FragPipe-$VERSION.tar.gz
cd FragPipe-$VERSION
# -------------------------------------------------------------- patch time
# several GUI patches, some are cosmetic, some are related
# to the fact that the installation directory is read only
cd ./MSFragger-GUI
# okay, we have them, so we also like to use them ...
sed -i -e '/^\s\s*public static final int maxProcessors/ s/= 128;/= 256;/' \
src/com/dmtavt/fragpipe/tabs/TabWorkflow.java
# ... and please do not call home on every start
sed -i \
-e "/raw.githubusercontent.com/ s|https.*PATH_BUNDLE|file://$PREFIX/etc/Bundle.properties\"|" \
-e '/^\s\s*+ ".properties"\s*$/ d' \
src/com/dmtavt/fragpipe/params/ThisAppProps.java
sed -ne '/^#Epatch:FragpipeLocations / s/^#Epatch:\S* // p' $ME | patch -p2 --verbose
sed -ne '/^#Epatch:Fragpipe / s/^#Epatch:\S* // p' $ME | patch -p2 --verbose
# ------------------------------------------------------------- compile now
# a full build, but it will not help with the file attributes, s.a. :/
# result: build/github-release/FragPipe-22.0.zip
# #> ./gradlew makeReleaseZipNoJre
# debug/devel builds for fragpipe-22.0.jar
# #> ./gradlew jar --rerun
# only the recompiled gui is needed ...
# result: build/libs/fragpipe-22.0.jar
./gradlew --console plain --max-workers $NPROC jar
mv -v build/libs/fragpipe-22.0.jar $PREFIX/lib
./gradlew --stop # since it is a 'daemon'
# ---------------------------------------------------------- finish install
cd $PREFIX
mkdir -p etc ltools updates workflows
# the file that is supposed to be downloaded from git-hub
cp -v build/FragPipe-22.0/MSFragger-GUI/src/com/dmtavt/fragpipe/Bundle.properties etc
# this works w/o further installing logging jars:
# JAVA_OPTS=-Dlogback.configurationFile=/package/fragpipe/etc/logback.xml fragpipe
rm -vf etc/logback.xml
sed -ne '/^#Epatch:logback/ s/^#Epatch:\S* // p' $ME | patch -p0 --verbose
# the academic license was acquired by H. Schmidt, some of the tools seem to
# talk with google analytics, just in case you wonder :)
REPO_LICENSED_SOFTWARE=/package/fragpipe/src
cd ltools
cp -p $REPO_LICENSED_SOFTWARE/2024-417_Academic_Research_Use_License_05142024.pdf .
bsdtar -xf $REPO_LICENSED_SOFTWARE/MSFragger-4.1.zip
bsdtar -xf $REPO_LICENSED_SOFTWARE/IonQuant-1.10.27.zip
bsdtar -xf $REPO_LICENSED_SOFTWARE/diaTracer-1.1.5.zip
# create a neater launcher, but also keep the funny one bundled
cat > $PREFIX/bin/mxfragpipe <<- EOF
#! /usr/bin/bash
set -e
# populate ~/.config/FragPipe/fragpipe/workflows on first start
XDG_CONFIG_HOME="\${XDG_CONFIG_HOME:-\$HOME/.config}"
export XDG_CONFIG_HOME
WORKFLOWDIR="\$XDG_CONFIG_HOME/FragPipe/fragpipe/workflows"
if [ ! -d "\$WORKFLOWDIR" ] ; then # assume first run ...
mkdir -vp "\$WORKFLOWDIR"
cp --preserve=timestamps /package/fragpipe/workflows.dist/* "\$WORKFLOWDIR"
echo 'fragpipe-config.tools-folder=$PREFIX/ltools' >> "\$XDG_CONFIG_HOME/FragPipe/fragpipe/fragpipe-ui.cache"
fi
# avoid stumbling over our filerunner or doublecommander apps
# grep -l inode/directory /usr/share/applications/*.desktop
if [ ! -e \$XDG_CONFIG_HOME/FragPipe/no_check_filemanager ]; then
FILEMANAGER=\$(xdg-mime query default inode/directory)
if [[ "\$FILEMANAGER" =~ 'doublecmd' || "\$FILEMANAGER" =~ 'filerunner' ]]; then
echo "# ==========================================================================="
echo "#"
echo "# NOTE: Your default filemanager application is set to \$FILEMANAGER ..."
echo "#"
echo "# to fix this issue and switch to thunar, enter:"
echo "# #> xdg-mime default thunar.desktop inode/directory"
echo "#"
echo "# to inhibit this message enter:"
echo "# #> touch \$XDG_CONFIG_HOME/FragPipe/no_check_filemanager"
echo "#"
echo "# ==========================================================================="
sleep 5
echo "# launching fragpipe now ..."
sleep 1
fi
fi
# -classpath '/foobar/lib/*' only adds *.jar files - ohh, what a surprise :)
exec java \$FRAGPIPE_OPTS \$JAVA_OPTS \\
-classpath '$PREFIX/lib/*' \\
com.dmtavt.fragpipe.FragPipeMain \\
"\${@+\$@}"
EOF
chmod +x $PREFIX/bin/mxfragpipe
echo '# Fragpipe install is done ...'
# ------------------------------------------------------------------ python
cd $BUILDDIR
# -------------------------------------- Use git to track package evolution
test -d .git && rm -rf .git
git init -q; echo -e '[user]\n name = none\n email = of_your_business...' >> .git/config
echo '*' > .gitignore
function piplist() {
pip list | awk '{ printf("%-36s %s\n", $1,$2) }' | grep -v '\----' > GameOfVersions
}
function track() {
if [ -d .git ]; then
if git add -f GameOfVersions; then
git commit -q -n -m "Package: '$*'" || /bin/true
fi
fi
}
function install() {
echo "# ::INST:: # '${@+$@}'"
# no-color is nice, but doesn't work when dependencies are installed, so (mis-)use a pipe
pip install --no-color --compile --cache-dir=$HOME/.cache/pip --prefix=$PREFIX "${@+$@}" | cat
piplist
track $*
}
# ---------------------------------------- Build Python & support libraries
(
# orig: https://www.python.org/ftp/python/3.11.11/Python-3.11.11.tgz
BEEHIVE=https://beehive.molgen.mpg.de/9a5b43fcc06810b8ae924b0a080e6569/Python-3.11.11.tgz
test -e Python-$PYTHONVER.tgz || wget -nv $BEEHIVE
test -d Python-$PYTHONVER || tar -xf Python-$PYTHONVER.tgz
cd Python-$PYTHONVER
# BerkeleyDB, the undead ...
# Newer libgdbm_compat.so versions pull libgdbm.so on their own, our libgdbm_compat.so is older ...
# So, let setup.py create '-lgdbm -lgdbm_compat' instead of a sole '-lgdbm_compat'
# verbatim: ndbm_libs = ['gdbm_compat'] => ndbm_libs = ['gdbm','gdbm_compat']
sed -i -e "/ndbm_libs = / s/_compat'/','gdbm_compat'/" setup.py
# leave further hints in the log
sed -i -e '/db_setup_debug = False/ s/False/True/' \
-e '/dbm_setup_debug = False/ s/False/True/' setup.py
# These may come handy if the Python build needs exclusive stuff from $PREFIX
# INCLUDEDIR=$PREFIX/include \
# LIBDIR=$PREFIX/lib \
LDFLAGS="-Wl,-rpath=$PREFIX/lib" \
./configure \
--prefix=$PREFIX \
--enable-shared
make -j $NPROC
make install
# it might come to happen that something down the line may just call 'python', defuse ...
test -e $PREFIX/bin/python || ln -s python3 $PREFIX/bin/python
python -m ensurepip
pip3 install --prefix=$PREFIX -I pip
( # fix 'please update' noise from pip
cd $PREFIX/lib/python*/site-packages
sed -ne '/^#Epatch:pip/ s/^#Epatch:\S* // p' $ME | patch -p1 --verbose
)
# I hate to do this ...
ln -s lib $PREFIX/lib64
)
install setuptools
piplist; track START
install Cython
install numpy==1.26.4 # The EasyPQP author nailed numpy to this version (needlessly of course, <2 is the right way ...)
install numba==0.60.0
install wheel
PACKAGES=$(sed -e s/#.*$// <<- __PKGLIST__
pyopenms==3.2.0
easypqp==0.1.50
lxml==5.3.0
__PKGLIST__
)
for PKG in $PACKAGES; do
install $PKG
done
# ------------------------------------------------------------ Sanity check
echo "# --------- *** SANITY CHECKS *** ---------"
# I guess it makes sense that files can be read by all users ...
echo "# 1) Check for unreadable files ..."
cd $PREFIX
for D in bin include lib share; do
find $D \! -perm -004 -exec chmod -c a+r {} +
done
# a cheap one :)
echo "# 2) Running pip check"
pip check
# load all packages, see warnings and spot installation errors
echo "# 3) Module load test."
export NUMEXPR_MAX_THREADS=1
python -c 'help("modules")'
echo "# Note: reached end of load test"
echo "For Deeper checks:"
echo "cd ${BUILDDIR} ; git log --patch | grep ^[\+\-][^\+\-]"
exit
# -------------------------------------------------------- Included patches
#Epatch:pip # Operation 'Forever young', disable version-check per default.
#Epatch:pip # The option needs to be kept, because some tools make use of
#Epatch:pip # it and would cause pip to fail.
#Epatch:pip --- a/pip/_internal/cli/cmdoptions.py 2022-08-09 17:29:15.853442948 +0200
#Epatch:pip +++ b/pip/_internal/cli/cmdoptions.py 2022-08-10 10:31:35.124945154 +0200
#Epatch:pip @@ -892,7 +892,6 @@
#Epatch:pip dest="disable_pip_version_check",
#Epatch:pip action="store_true",
#Epatch:pip - default=False,
#Epatch:pip - help="Don't periodically check PyPI to determine whether a new version "
#Epatch:pip - "of pip is available for download. Implied with --no-index.",
#Epatch:pip + default=True,
#Epatch:pip + help="Ignore this option, the version check IS disabled.",
#Epatch:pip )
#Epatch:jarredater --- jarredater
#Epatch:jarredater +++ jarredater
#Epatch:jarredater @@ -0,0 +1,13 @@
#Epatch:jarredater +import os, sys, time, zipfile
#Epatch:jarredater +
#Epatch:jarredater +dt_list = []
#Epatch:jarredater +if len(sys.argv) > 1:
#Epatch:jarredater + for f in sys.argv[1:]:
#Epatch:jarredater + dt_list.clear()
#Epatch:jarredater + zf = zipfile.ZipFile(f, 'r')
#Epatch:jarredater + for i in zf.infolist(): dt_list.append(i.date_time)
#Epatch:jarredater + zf.close()
#Epatch:jarredater + maxtime = max( dt_list )
#Epatch:jarredater + print('# touching', f, '->', maxtime)
#Epatch:jarredater + epo = time.mktime( maxtime + (0,0,0) )
#Epatch:jarredater + os.utime(f, (epo, epo))
#Epatch:logback --- etc/logback.xml
#Epatch:logback +++ etc/logback.xml
#Epatch:logback @@ -0,0 +1,12 @@
#Epatch:logback +<configuration>
#Epatch:logback + <!-- enable: JAVA_OPTS=-Dlogback.configurationFile=/path/to/logback.xml fragpipe -->
#Epatch:logback + <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
#Epatch:logback + <encoder>
#Epatch:logback + <pattern>%d %-5level %-42logger{42} - %msg%n</pattern>
#Epatch:logback + </encoder>
#Epatch:logback + </appender>
#Epatch:logback + <logger name="com.dmtavt.fragpipe.api.FragpipeCacheUtils" level="error" />
#Epatch:logback + <root level="debug">
#Epatch:logback + <appender-ref ref="STDOUT" />
#Epatch:logback + </root>
#Epatch:logback +</configuration>
### =========================================================================================
### VERY CAREFUL NOW, we are patchin WinDos files, lookout for '<cr>' / '^M' in your editor !
### =========================================================================================
#Epatch:FragpipeLocations diff --git a/MSFragger-GUI/src/com/dmtavt/fragpipe/FragpipeLocations.java b/MSFragger-GUI/src/com/dmtavt/fragpipe/FragpipeLocations.java
#Epatch:FragpipeLocations index 6f14590e..58f56d5f 100644
#Epatch:FragpipeLocations --- a/MSFragger-GUI/src/com/dmtavt/fragpipe/FragpipeLocations.java
#Epatch:FragpipeLocations +++ b/MSFragger-GUI/src/com/dmtavt/fragpipe/FragpipeLocations.java
#Epatch:FragpipeLocations @@ -106,8 +106,9 @@ public class FragpipeLocations {
#Epatch:FragpipeLocations tools = dir.resolve(Paths.get("../tools"));
#Epatch:FragpipeLocations }
#Epatch:FragpipeLocations
#Epatch:FragpipeLocations - Path workflows = dir.resolve("../workflows");
#Epatch:FragpipeLocations - Path longTermStorage = CacheUtils.getTempDir();
#Epatch:FragpipeLocations + // Path workflows = dir.resolve("../workflows");
#Epatch:FragpipeLocations + Path workflows = dir.resolve( CacheUtils.getTempDir().toString() + "/workflows" );
#Epatch:FragpipeLocations + Path longTermStorage = CacheUtils.getTempDir(); // well this yields to > XDG_CONFIG_HOME + "/FragPipe" <
#Epatch:FragpipeLocations
#Epatch:FragpipeLocations // create locations if they don't yet exist
#Epatch:FragpipeLocations List<Path> paths = Arrays.asList(dir, cache, tools, workflows, longTermStorage);
#Epatch:Fragpipe diff --git a/MSFragger-GUI/src/com/dmtavt/fragpipe/Fragpipe.java b/MSFragger-GUI/src/com/dmtavt/fragpipe/Fragpipe.java
#Epatch:Fragpipe index 16fd82ec..64696321 100644
#Epatch:Fragpipe --- a/MSFragger-GUI/src/com/dmtavt/fragpipe/Fragpipe.java
#Epatch:Fragpipe +++ b/MSFragger-GUI/src/com/dmtavt/fragpipe/Fragpipe.java
#Epatch:Fragpipe @@ -289,22 +289,36 @@ public class Fragpipe extends JFrameHeadless {
#Epatch:Fragpipe log.debug("Saving ui cache: collected {} properties from UI. Size after merging with cached object: {}.",
#Epatch:Fragpipe tabsAsProps.size(), cache.propsUiState.size());
#Epatch:Fragpipe try {
#Epatch:Fragpipe - cache.propsUiState.setPath(FragpipeLocations.get().getPathUiCache(false));
#Epatch:Fragpipe - cache.propsUiState.save();
#Epatch:Fragpipe + // when we fail here (lib/../cache), the other one will not be written out :/
#Epatch:Fragpipe + //cache.propsUiState.setPath(FragpipeLocations.get().getPathUiCache(false));
#Epatch:Fragpipe + //cache.propsUiState.save();
#Epatch:Fragpipe cache.propsUiState.setPath(FragpipeLocations.get().getPathUiCache(true));
#Epatch:Fragpipe cache.propsUiState.save();
#Epatch:Fragpipe } catch (IOException ex) {
#Epatch:Fragpipe - log.error("Error saving ui cache. It won't affect the results.");
#Epatch:Fragpipe + log.error("Error saving ui cache. It won't affect the results." + " (" +
#Epatch:Fragpipe + FragpipeLocations.get().getPathUiCache(true) + ")"
#Epatch:Fragpipe + );
#Epatch:Fragpipe }
#Epatch:Fragpipe try {
#Epatch:Fragpipe - cache.propsRuntime.setPath(FragpipeLocations.get().getPathRuntimeCache(false));
#Epatch:Fragpipe - cache.propsRuntime.save();
#Epatch:Fragpipe + // when we fail here (lib/../cache), the other one will not be written out :/
#Epatch:Fragpipe + //cache.propsRuntime.setPath(FragpipeLocations.get().getPathRuntimeCache(false));
#Epatch:Fragpipe + //cache.propsRuntime.save();
#Epatch:Fragpipe cache.propsRuntime.setPath(FragpipeLocations.get().getPathRuntimeCache(true));
#Epatch:Fragpipe cache.propsRuntime.save();
#Epatch:Fragpipe } catch (IOException ex) {
#Epatch:Fragpipe - log.error("Error saving runtime cache. It won't affect the results.");
#Epatch:Fragpipe + log.error("Error saving runtime cache. It won't affect the results." + " (" +
#Epatch:Fragpipe + FragpipeLocations.get().getPathRuntimeCache(true) + ")"
#Epatch:Fragpipe + );
#Epatch:Fragpipe }
#Epatch:Fragpipe
#Epatch:Fragpipe + /*
#Epatch:Fragpipe +
#Epatch:Fragpipe + -- skipping this for the moment --
#Epatch:Fragpipe +
#Epatch:Fragpipe + - copy the existing workflows on first start (done by the starter script)
#Epatch:Fragpipe + - then use the users XDG_CONFIG_HOME/FragPipe/fragpipe/workflows directory
#Epatch:Fragpipe + as the sole source for workflows
#Epatch:Fragpipe +
#Epatch:Fragpipe // saving workflows
#Epatch:Fragpipe Path dirWorkflows = FragpipeLocations.get().getDirWorkflows();
#Epatch:Fragpipe Path lts = FragpipeLocations.get().getPathLongTermStorage().resolve(dirWorkflows.getFileName());
#Epatch:Fragpipe @@ -315,6 +329,8 @@ public class Fragpipe extends JFrameHeadless {
#Epatch:Fragpipe log.error("Error saving workflows between sessions.");
#Epatch:Fragpipe throw new IllegalStateException(e);
#Epatch:Fragpipe }
#Epatch:Fragpipe + */
#Epatch:Fragpipe +
#Epatch:Fragpipe }
#Epatch:Fragpipe
#Epatch:Fragpipe public static FormEntry.Builder fe(JComponent comp, String compName) {
#Epatch:Fragpipe @@ -385,9 +401,11 @@ public class Fragpipe extends JFrameHeadless {
#Epatch:Fragpipe System.exit(1);
#Epatch:Fragpipe }
#Epatch:Fragpipe
#Epatch:Fragpipe + /* why are linux users forced to use 'Nimbus' ?
#Epatch:Fragpipe if (!headless) {
#Epatch:Fragpipe SwingUtils.setLaf();
#Epatch:Fragpipe }
#Epatch:Fragpipe + */
#Epatch:Fragpipe
#Epatch:Fragpipe FragpipeLoader fragpipeLoader = new FragpipeLoader();
#Epatch:Fragpipe Bus.register(fragpipeLoader);