diff options
-rw-r--r-- | .SRCINFO | 47 | ||||
-rw-r--r-- | PKGBUILD | 117 | ||||
-rwxr-xr-x | commonify | 184 |
3 files changed, 348 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 000000000000..4ce2ea1b9d0c --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,47 @@ +pkgbase = eclipse + pkgdesc = Highly extensible IDE + pkgver = 4.15 + pkgrel = 2 + url = https://eclipse.org + arch = x86_64 + license = EPL + makedepends = python3 + noextract = eclipse-java-2020-03-R-linux-gtk-x86_64.tar.gz + noextract = eclipse-jee-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + noextract = eclipse-cpp-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + noextract = eclipse-php-2020-03-R-linux-gtk-x86_64.tar.gz + noextract = eclipse-javascript-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + noextract = eclipse-rust-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + source = commonify + sha256sums = a68cccdf182449dfb4aef595ab26fe6542902421aef42a79672483865cbbd0ea + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-java-2020-03-R-linux-gtk-x86_64.tar.gz + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-jee-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-cpp-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-php-2020-03-R-linux-gtk-x86_64.tar.gz + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-javascript-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + source_x86_64 = http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/2020-03/R/eclipse-rust-2020-03-R-incubation-linux-gtk-x86_64.tar.gz + sha256sums_x86_64 = 72fde94154999df569cbd30551bc784341391b9753209cd563829a6c8674383e + sha256sums_x86_64 = 1f6b44cc8a8665f452170f395523486e3555570174768d96d8ca7e2bacc3f31d + sha256sums_x86_64 = 3cc546c7bd9214ca834cf5d8bcd16e300ae0fa95f1bf49e15c52ea47235b7f01 + sha256sums_x86_64 = 0d6662d7a57585320f441029358261c23e570bf7779cbe34ee2f91208b2aff54 + sha256sums_x86_64 = 25a2e502e33c0a4b6629b35dfb140d5bd772d932ca472e554f672524d189caec + sha256sums_x86_64 = c52860b6134e083aa263d1c1eb80f4a904cdf284d25f7aaee472950386347109 + +pkgname = eclipse-common + pkgdesc = Highly extensible IDE (common files) + depends = java-environment>=8 + depends = webkit2gtk + depends = unzip + +pkgname = eclipse-java + +pkgname = eclipse-jee + +pkgname = eclipse-cpp + +pkgname = eclipse-php + +pkgname = eclipse-javascript + +pkgname = eclipse-rust + diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 000000000000..632ba80b4465 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,117 @@ +# Maintainer: Jan Alexander Steffens (heftig) <jan.steffens@gmail.com> +# Contributor: Carson Black <uhhadd@gmail.com> +# Contributor: Ionut Biru <ibiru@archlinux.org> +# Contributor: Paul Mattal <paul@archlinux.org> +# Contributor: Andrew Wright <andreww@photism.org> +# Contributor: Andreas W. Hauser <andy-aur@splashground.de> +# Contributor: Marco Crosio <marco.crosio@gmail.com> + +pkgbase=eclipse +pkgname=(eclipse-{common,java,jee,cpp,php,javascript,rust}) +pkgver=4.15 +pkgrel=2 +_release=2020-03/R +pkgdesc="Highly extensible IDE" +license=(EPL) +arch=(x86_64) +url="https://eclipse.org" +makedepends=(python3) +source=(commonify) +sha256sums=('a68cccdf182449dfb4aef595ab26fe6542902421aef42a79672483865cbbd0ea') +sha256sums_x86_64=('72fde94154999df569cbd30551bc784341391b9753209cd563829a6c8674383e' + '1f6b44cc8a8665f452170f395523486e3555570174768d96d8ca7e2bacc3f31d' + '3cc546c7bd9214ca834cf5d8bcd16e300ae0fa95f1bf49e15c52ea47235b7f01' + '0d6662d7a57585320f441029358261c23e570bf7779cbe34ee2f91208b2aff54' + '25a2e502e33c0a4b6629b35dfb140d5bd772d932ca472e554f672524d189caec' + 'c52860b6134e083aa263d1c1eb80f4a904cdf284d25f7aaee472950386347109') + +_sourcename() { + case $1 in + eclipse-common) return 1 ;; + eclipse-rust | eclipse-jee | eclipse-cpp | eclipse-javascript) echo $1-${_release//\//-}-incubation-linux-gtk-x86_64.tar.gz ;; + * ) echo $1-${_release//\//-}-linux-gtk-x86_64.tar.gz ;; + esac +} + +source_x86_64=() +noextract=() + +for _pkg in ${pkgname[@]}; do + _src=$(_sourcename $_pkg) || continue + source_x86_64+=(http://ftp-stud.fht-esslingen.de/pub/Mirrors/eclipse/technology/epp/downloads/release/$_release/$_src) + noextract+=($_src) + eval "package_$_pkg() { _package $_pkg; }" +done + + +prepare() { + local pkg src + for pkg in ${pkgname[@]}; do + mkdir $pkg + src=$(_sourcename $pkg) || continue + bsdtar -xf $src -C $pkg --strip-components 1 + done +} + +build() { + mkdir eclipse-common/dropins + touch eclipse-common/dropins/.keep + ./commonify --identical ${pkgname[@]} +} + +package_eclipse-common() { + pkgdesc+=" (common files)" + depends=("java-environment>=8" webkit2gtk unzip) + + install -d "$pkgdir/usr/lib" + cp -a eclipse-common "$pkgdir/usr/lib/eclipse" +} + +_package() { + local variant i + + case ${1#eclipse-} in + java ) variant=Java; replaces=(eclipse) ;; + jee ) variant=JEE ;; + cpp ) variant=C++; replaces=(eclipse-cdt) ;; + php ) variant=PHP ;; + javascript) variant=JavaScript ;; + rust ) variant=Rust ;; + * ) return 1 ;; + esac + + _lower=${variant,,} + + pkgdesc+=" for $variant" + depends=("eclipse-common=$pkgver-$pkgrel" bash) + provides=("eclipse=$pkgver-$pkgrel") + + install -d "$pkgdir/usr/lib" + cp -a $1 "$pkgdir/usr/lib/eclipse-${_lower}" + + install -D /dev/stdin "$pkgdir/usr/bin/eclipse-${_lower}" <<END +#!/bin/bash +export ECLIPSE_HOME=/usr/lib/eclipse-"${_lower}" +exec /usr/lib/eclipse/eclipse "\$@" +END + + install -Dm644 /dev/stdin "$pkgdir/usr/share/applications/eclipse-${_lower}.desktop" <<END +[Desktop Entry] +Name=Eclipse $variant +Comment=$variant Development Environment +Icon=eclipse-${_lower} +Exec=eclipse-${_lower} +Terminal=false +Type=Application +Categories=Development;IDE;Java; +StartupNotify=true +END + + sed -i "$ a -classpath \"/usr/lib/eclipse:/usr/lib/eclipse-${_lower}:.\"" "$pkgdir/usr/lib/eclipse-${_lower}/eclipse.ini" + sed -i "s%-Dosgi.instance.area.default=@user.home/eclipse-workspace%-Dosgi.instance.area.default=@user.home/eclipse-${_lower}-workspace%g" "$pkgdir/usr/lib/eclipse-${_lower}/eclipse.ini" + + for i in 16 22 24 32 48 64 128 256 512 1024; do + install -Dm644 eclipse-common/plugins/org.eclipse.platform_*/eclipse$i.png \ + "$pkgdir/usr/share/icons/hicolor/${i}x$i/apps/eclipse-${_lower}.png" + done +} diff --git a/commonify b/commonify new file mode 100755 index 000000000000..f45029eb7ed3 --- /dev/null +++ b/commonify @@ -0,0 +1,184 @@ +#!/usr/bin/env python3 +from argparse import ArgumentParser +from asyncio import ( + BoundedSemaphore, + IncompleteReadError, + create_subprocess_exec, + gather, + get_running_loop, + run, +) +from asyncio.subprocess import DEVNULL, PIPE +from contextlib import asynccontextmanager +from enum import Enum, auto +from logging import DEBUG, INFO, basicConfig, getLogger +from os import cpu_count, remove, removedirs, renames +from os.path import isdir, join as pjoin, relpath, split as psplit +from sys import exit + +logger = getLogger(__name__) + + +class Mode(Enum): + identical = auto() + nonconflicting = auto() + + +def parse_args(args=None): + parser = ArgumentParser(description="Extract common files.") + + modes = parser.add_mutually_exclusive_group(required=True) + for m in Mode: + modes.add_argument( + f"--{m.name}", + dest="mode", + action="store_const", + const=m, + help=f"extract {m.name} common files", + ) + + parser.add_argument("-n", "--dry-run", action="store_true", help="Dry run (do nothing)") + parser.add_argument("-v", "--verbose", action="store_true", help="Raise verbosity") + parser.add_argument( + "common_dir", metavar="COMMON_DIR", help="common files directory to move to" + ) + parser.add_argument("targets", nargs="+", metavar="INPUT_DIR", help="directory to move from") + + return parser.prog, parser.parse_args(args) + + +@asynccontextmanager +async def bounded_exec(*args, **kwargs): + loop = get_running_loop() + + try: + semaphore = loop.__bounded_exec_semaphore + except AttributeError: + semaphore = loop.__bounded_exec_semaphore = BoundedSemaphore(value=cpu_count() + 1) + + async with semaphore: + process = await create_subprocess_exec(*args, **kwargs) + try: + yield process + finally: + if process.returncode is None: + try: + process.kill() + except OSError: + pass + await process.wait() + + +class DiffError(RuntimeError): + pass + + +async def diff(file1, file2): + async with bounded_exec( + "diff", "-q", file1, file2, stdin=DEVNULL, stdout=DEVNULL, stderr=DEVNULL + ) as p: + ret = await p.wait() + + if ret != 0: + raise DiffError() + + +async def identical(files): + if len(files) < 2: + return True + first, *rest = files + fut = gather(*[diff(first, f) for f in rest]) + try: + await fut + except DiffError: + return False + else: + return True + finally: + fut.cancel() + + +def removes(path): + remove(path) + head, tail = psplit(path) + if head and tail: + try: + removedirs(head) + except OSError: + pass + + +def commonify_file(common_file, files): + first, *rest = files + renames(first, common_file) + for f in rest: + removes(f) + + +async def find_files(path): + async with bounded_exec( + "find", path, "-type", "f", "-print0", stdin=DEVNULL, stdout=PIPE, stderr=DEVNULL + ) as p: + while True: + try: + line = await p.stdout.readuntil(b"\x00") + except IncompleteReadError as e: + line = e.partial + if not line: + break + raise + yield line[:-1].decode() + + +async def scan_one(target, files): + n = 0 + async for f in find_files(target): + files.setdefault(relpath(f, target), []).append(target) + n += 1 + logger.info("Found %d files in %r", n, target) + + +async def scan(targets): + files = {} + await gather(*[scan_one(t, files) for t in targets]) + return files + + +def arg_dir(s): + if not isdir(s): + raise ValueError(f"{s!r} is not a directory") + return s + + +async def commonify(settings, common_file, targets): + files = [pjoin(t, common_file) for t in targets] + + if not await identical(files): + logger.info("Divergent file %r", common_file) + return False + + if len(files) == len(settings.targets): + logger.debug("Identical file %r", common_file) + elif settings.mode == Mode.nonconflicting: + logger.debug("Nonconflicting file %r in %r", common_file, targets) + else: + logger.debug("Partly identical file %r in %r", common_file, targets) + return False + + if not settings.dry_run: + commonify_file(pjoin(settings.common_dir, common_file), files) + + return True + + +async def main(settings): + files = await scan(arg_dir(t) for t in settings.targets) + results = await gather(*[commonify(settings, *ft) for ft in files.items()]) + logger.info("%d %s files in %r", sum(results), settings.mode.name, settings.common_dir) + return 0 + + +if __name__ == "__main__": + prog, settings = parse_args() + basicConfig(level=DEBUG if settings.verbose else INFO, format=f"{prog}: %(message)s") + exit(run(main(settings), debug=settings.verbose)) |