summarylogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.SRCINFO47
-rw-r--r--PKGBUILD117
-rwxr-xr-xcommonify184
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))