mirror of
https://github.com/arcan1s/ahriman.git
synced 2025-08-30 13:29:55 +00:00
Compare commits
2 Commits
3fa3cc46ad
...
f09082dff2
Author | SHA1 | Date | |
---|---|---|---|
f09082dff2 | |||
8d53a59a6a |
@ -226,7 +226,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
pass
|
||||
case PkgbuildToken.ArrayEnds:
|
||||
break
|
||||
case PkgbuildToken.Comment:
|
||||
case comment if comment.startswith(PkgbuildToken.Comment):
|
||||
self.instream.readline()
|
||||
continue
|
||||
|
||||
@ -267,7 +267,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
counter -= 1
|
||||
if counter == 0:
|
||||
break
|
||||
case PkgbuildToken.Comment:
|
||||
case comment if comment.startswith(PkgbuildToken.Comment):
|
||||
self.instream.readline()
|
||||
|
||||
if not 0 < start_position < end_position:
|
||||
@ -303,7 +303,7 @@ class PkgbuildParser(shlex.shlex):
|
||||
yield PkgbuildPatch(key, value)
|
||||
return
|
||||
|
||||
if token == PkgbuildToken.Comment:
|
||||
if token.startswith(PkgbuildToken.Comment):
|
||||
self.instream.readline()
|
||||
return
|
||||
|
||||
|
@ -59,10 +59,10 @@ class Mapping(Auth):
|
||||
"""
|
||||
if password is None:
|
||||
return False # invalid data supplied
|
||||
user = self.get_user(username)
|
||||
user = await self.get_user(username)
|
||||
return user is not None and user.check_credentials(password, self.salt)
|
||||
|
||||
def get_user(self, username: str) -> User | None:
|
||||
async def get_user(self, username: str) -> User | None:
|
||||
"""
|
||||
retrieve user from in-memory mapping
|
||||
|
||||
@ -84,7 +84,7 @@ class Mapping(Auth):
|
||||
Returns:
|
||||
bool: ``True`` in case if user is known and can be authorized and ``False`` otherwise
|
||||
"""
|
||||
return username is not None and self.get_user(username) is not None
|
||||
return username is not None and await self.get_user(username) is not None
|
||||
|
||||
async def verify_access(self, username: str, required: UserAccess, context: str | None) -> bool:
|
||||
"""
|
||||
@ -98,5 +98,5 @@ class Mapping(Auth):
|
||||
Returns:
|
||||
bool: ``True`` in case if user is allowed to do this request and ``False`` otherwise
|
||||
"""
|
||||
user = self.get_user(username)
|
||||
user = await self.get_user(username)
|
||||
return user is not None and user.verify_access(required)
|
||||
|
@ -120,7 +120,7 @@ class PAM(Mapping):
|
||||
bool: ``True`` in case if user is allowed to do this request and ``False`` otherwise
|
||||
"""
|
||||
# this method is basically inverted, first we check overrides in database and then fallback to the PAM logic
|
||||
if (user := self.get_user(username)) is not None:
|
||||
if (user := await self.get_user(username)) is not None:
|
||||
return user.verify_access(required)
|
||||
# if username is in admin group, then we treat it as full access
|
||||
if username in self.group_members(self.full_access_group):
|
||||
|
@ -32,6 +32,7 @@ class User:
|
||||
authorized web user model
|
||||
|
||||
Attributes:
|
||||
SUPPORTED_ALGOS(set[str]): (class attribute) list of the supported hashing algorithms
|
||||
username(str): username
|
||||
password(str): hashed user password with salt
|
||||
access(UserAccess): user role
|
||||
@ -68,6 +69,8 @@ class User:
|
||||
packager_id: str | None = None
|
||||
key: str | None = None
|
||||
|
||||
SUPPORTED_ALGOS = {"$2$", "$2a$", "$2x$", "$2y$", "$2b$"}
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
"""
|
||||
remove empty fields
|
||||
@ -75,6 +78,19 @@ class User:
|
||||
object.__setattr__(self, "packager_id", self.packager_id or None)
|
||||
object.__setattr__(self, "key", self.key or None)
|
||||
|
||||
@property
|
||||
def algo(self) -> str | None:
|
||||
"""
|
||||
extract algorithm used for the hashing password
|
||||
|
||||
Returns:
|
||||
str | None: first part of password hash (e.g. ``$2$``) if available or ``None`` otherwise
|
||||
"""
|
||||
if not self.password:
|
||||
return None
|
||||
algo = next(segment for segment in self.password.split("$") if segment)
|
||||
return f"${algo}$"
|
||||
|
||||
@staticmethod
|
||||
def generate_password(length: int) -> str:
|
||||
"""
|
||||
@ -98,7 +114,12 @@ class User:
|
||||
|
||||
Returns:
|
||||
bool: ``True`` in case if password matches, ``False`` otherwise
|
||||
|
||||
Raises:
|
||||
ValueError: if user password is set to unsupported algorithm
|
||||
"""
|
||||
if (algo := self.algo) is not None and algo not in self.SUPPORTED_ALGOS:
|
||||
raise ValueError(f"Crypt {algo} is not supported, consider setting new password")
|
||||
try:
|
||||
return bcrypt.checkpw((password + salt).encode("utf8"), self.password.encode("utf8"))
|
||||
except ValueError:
|
||||
|
@ -31,27 +31,27 @@ async def test_check_credentials_unknown(mapping: Mapping, user: User) -> None:
|
||||
assert not await mapping.check_credentials(user.username, user.password)
|
||||
|
||||
|
||||
def test_get_user(mapping: Mapping, user: User, mocker: MockerFixture) -> None:
|
||||
async def test_get_user(mapping: Mapping, user: User, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return user from storage by username
|
||||
"""
|
||||
mocker.patch("ahriman.core.database.SQLite.user_get", return_value=user)
|
||||
assert mapping.get_user(user.username) == user
|
||||
assert await mapping.get_user(user.username) == user
|
||||
|
||||
|
||||
def test_get_user_normalized(mapping: Mapping, user: User, mocker: MockerFixture) -> None:
|
||||
async def test_get_user_normalized(mapping: Mapping, user: User, mocker: MockerFixture) -> None:
|
||||
"""
|
||||
must return user from storage by username case-insensitive
|
||||
"""
|
||||
mocker.patch("ahriman.core.database.SQLite.user_get", return_value=user)
|
||||
assert mapping.get_user(user.username.upper()) == user
|
||||
assert await mapping.get_user(user.username.upper()) == user
|
||||
|
||||
|
||||
def test_get_user_unknown(mapping: Mapping, user: User) -> None:
|
||||
async def test_get_user_unknown(mapping: Mapping, user: User) -> None:
|
||||
"""
|
||||
must return None in case if no user found
|
||||
"""
|
||||
assert mapping.get_user(user.username) is None
|
||||
assert await mapping.get_user(user.username) is None
|
||||
|
||||
|
||||
async def test_known_username(mapping: Mapping, user: User, mocker: MockerFixture) -> None:
|
||||
|
@ -472,6 +472,7 @@ def test_walk(resource_path_root: Path) -> None:
|
||||
resource_path_root / "models" / "package_gcc10_pkgbuild",
|
||||
resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild",
|
||||
resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild",
|
||||
resource_path_root / "models" / "package_vim-youcompleteme-git_pkgbuild",
|
||||
resource_path_root / "models" / "package_yay_pkgbuild",
|
||||
resource_path_root / "models" / "pkgbuild",
|
||||
resource_path_root / "models" / "utf8",
|
||||
|
@ -386,3 +386,66 @@ def test_parse_yay(resource_path_root: Path) -> None:
|
||||
"source": ["${pkgname}-${pkgver}.tar.gz::https://github.com/Jguer/yay/archive/v${pkgver}.tar.gz"],
|
||||
"sha256sums": ["2fb6121a6eb4c5e6afaf22212b2ed15022500a4bc34bb3dc0f9782c1d43c3962"],
|
||||
}
|
||||
|
||||
|
||||
def test_parse_vim_youcompleteme_git(resource_path_root: Path) -> None:
|
||||
"""
|
||||
must parse real PKGBUILDs correctly (vim-youcompleteme-git)
|
||||
"""
|
||||
pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_vim-youcompleteme-git_pkgbuild")
|
||||
values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function}
|
||||
assert values == {
|
||||
"pkgbase": "vim-youcompleteme-git",
|
||||
"_gocode": "y",
|
||||
"_typescript": "y",
|
||||
"_tern": "n",
|
||||
"_java": "y",
|
||||
"_use_system_clang": "ON",
|
||||
"_use_system_abseil": "OFF",
|
||||
"_neovim": "$NEOVIM_YOUCOMPLETEME",
|
||||
"pkgname": "vim-youcompleteme-git",
|
||||
"pkgver": "r3216.0d855962",
|
||||
"pkgrel": "1",
|
||||
"pkgdesc": "A code-completion engine for Vim",
|
||||
"arch": ["x86_64"],
|
||||
"url": "https://ycm-core.github.io/YouCompleteMe/",
|
||||
"license": ["GPL3"],
|
||||
"groups": ["vim-plugins"],
|
||||
"depends": [
|
||||
"vim",
|
||||
"python>=3.6",
|
||||
"python-watchdog",
|
||||
"python-bottle",
|
||||
"clang"
|
||||
],
|
||||
"makedepends": [
|
||||
"git",
|
||||
"cmake",
|
||||
"pybind11",
|
||||
],
|
||||
"optdepends": [
|
||||
"gopls: Go semantic completion",
|
||||
"nodejs-tern: JavaScript semantic completion",
|
||||
"rust-analyzer: Rust semantic completion",
|
||||
"typescript: Typescript semantic completion",
|
||||
"python-jedi: Python semantic completion",
|
||||
"python-numpydoc: Python semantic completion",
|
||||
"python-regex: Better Unicode support",
|
||||
"omnisharp-roslyn: C# semantic completion",
|
||||
"java-environment>=11: Java semantic completion",
|
||||
"jdtls: Java semantic completion",
|
||||
"abseil-cpp: if setting _use_system_abseil ON",
|
||||
],
|
||||
"source": [
|
||||
"git+https://github.com/ycm-core/YouCompleteMe.git",
|
||||
"git+https://github.com/ycm-core/ycmd.git",
|
||||
"clangd-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/clangd-15.0.1-x86_64-unknown-linux-gnu.tar.bz2",
|
||||
"libclang-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/libclang-15.0.1-x86_64-unknown-linux-gnu.tar.bz2",
|
||||
],
|
||||
"sha256sums": [
|
||||
"SKIP",
|
||||
"SKIP",
|
||||
"10a64c468d1dd2a384e0e5fd4eb2582fd9f1dfa706b6d2d2bb88fb0fbfc2718d",
|
||||
"9a5bee818a4995bc52e91588059bef42728d046808206bfb93977f4e3109e50c",
|
||||
],
|
||||
}
|
||||
|
@ -1,9 +1,29 @@
|
||||
import pytest
|
||||
|
||||
from dataclasses import replace
|
||||
|
||||
from ahriman.models.user import User
|
||||
from ahriman.models.user_access import UserAccess
|
||||
|
||||
|
||||
def test_algo() -> None:
|
||||
"""
|
||||
must correctly define algorithm used
|
||||
"""
|
||||
assert User(username="user", password=None, access=UserAccess.Read).algo is None
|
||||
assert User(username="user", password="", access=UserAccess.Read).algo is None
|
||||
assert User(
|
||||
username="user",
|
||||
password="$6$rounds=656000$mWBiecMPrHAL1VgX$oU4Y5HH8HzlvMaxwkNEJjK13ozElyU1wAHBoO/WW5dAaE4YEfnB0X3FxbynKMl4FBdC3Ovap0jINz4LPkNADg0",
|
||||
access=UserAccess.Read,
|
||||
).algo == "$6$"
|
||||
assert User(
|
||||
username="user",
|
||||
password="$2b$12$VCWKazvYxH7B0eAalDGAbu/3y1dSWs79sv/2ujjX1TMaFdVUy80hy",
|
||||
access=UserAccess.Read,
|
||||
).algo == "$2b$"
|
||||
|
||||
|
||||
def test_check_credentials_hash_password(user: User) -> None:
|
||||
"""
|
||||
must generate and validate user password
|
||||
@ -20,11 +40,23 @@ def test_check_credentials_empty_hash(user: User) -> None:
|
||||
must reject any authorization if the hash is invalid
|
||||
"""
|
||||
current_password = user.password
|
||||
assert not user.check_credentials(current_password, "salt")
|
||||
user = replace(user, password="")
|
||||
assert not user.check_credentials(current_password, "salt")
|
||||
|
||||
|
||||
def test_check_credentials_sha512() -> None:
|
||||
"""
|
||||
must raise DeprecationWarning for sha512 hashed passwords
|
||||
"""
|
||||
user = User(
|
||||
username="user",
|
||||
password="$6$rounds=656000$mWBiecMPrHAL1VgX$oU4Y5HH8HzlvMaxwkNEJjK13ozElyU1wAHBoO/WW5dAaE4YEfnB0X3FxbynKMl4FBdC3Ovap0jINz4LPkNADg0",
|
||||
access=UserAccess.Read,
|
||||
)
|
||||
with pytest.raises(ValueError):
|
||||
assert user.check_credentials("password", "salt")
|
||||
|
||||
|
||||
def test_hash_password_empty_hash(user: User) -> None:
|
||||
"""
|
||||
must return empty string after hash in case if password not set
|
||||
|
@ -0,0 +1,177 @@
|
||||
# Maintainer: Leonidas Spyropoulos <artafinde at gmail dot com>
|
||||
# Contributor: staletic
|
||||
# Contributor: James Brink <brink.james@gmail.com>
|
||||
# Contributor: Wilson E. Alvarez <wilson.e.alvarez1@gmail.com>
|
||||
# Contributor: p <parimal@beyond8labs.com>
|
||||
# Contributor: Victor <victor@xirion.net>
|
||||
# Contributor: Jan-Tarek Butt <tarek AT ring0 DOT de>
|
||||
# Contributor: Erik Beran <eberan AT gmail DOT com>
|
||||
# Contributor: Thor K. H. <thor at roht dot no>
|
||||
# Contributor: Babken Vardanyan <483ken 4tgma1l
|
||||
# Contributor: mikezackles
|
||||
# Contributor: z33ky
|
||||
# Contributor: stykr
|
||||
# Contributor: Svenstaro
|
||||
# Contributor: KaiSforza
|
||||
# Contributor: Simon Gomizelj <simongmzlj@gmail.com>
|
||||
# Contributor: Daniel Micay <danielmicay@gmail.com>
|
||||
# Contributor: shmilee
|
||||
# Contributor: foobster
|
||||
# Contributor: archdria
|
||||
# Contributor: Andy Weidenbaum <archbaum@gmail.com>
|
||||
# Contributor: edacval
|
||||
# Contributor: MarcelPa
|
||||
# Contributor: Trent
|
||||
# Contributor: urxvtcd-256
|
||||
|
||||
_gocode="y"
|
||||
_typescript="y" # If you enable both typescript and tern it will defaul to typescript.
|
||||
_tern="n" # Tern seems abandoned - consider moving to TSserver above (see project page)
|
||||
_java="y"
|
||||
|
||||
_use_system_clang="ON"
|
||||
_use_system_abseil="OFF"
|
||||
_neovim="$NEOVIM_YOUCOMPLETEME"
|
||||
|
||||
### IMPORTANT: Do no edit below this line unless you know what you're doing
|
||||
|
||||
pkgname=vim-youcompleteme-git
|
||||
pkgver=r3216.0d855962
|
||||
pkgrel=1
|
||||
pkgdesc='A code-completion engine for Vim'
|
||||
arch=('x86_64')
|
||||
url='https://ycm-core.github.io/YouCompleteMe/'
|
||||
license=('GPL3')
|
||||
groups=('vim-plugins')
|
||||
depends=('vim' 'python>=3.6' 'python-watchdog' 'python-bottle' 'clang')
|
||||
makedepends=('git' 'cmake' 'pybind11')
|
||||
optdepends=(
|
||||
'gopls: Go semantic completion'
|
||||
'nodejs-tern: JavaScript semantic completion'
|
||||
'rust-analyzer: Rust semantic completion'
|
||||
'typescript: Typescript semantic completion'
|
||||
'python-jedi: Python semantic completion'
|
||||
'python-numpydoc: Python semantic completion'
|
||||
'python-regex: Better Unicode support'
|
||||
'omnisharp-roslyn: C# semantic completion'
|
||||
'java-environment>=11: Java semantic completion'
|
||||
'jdtls: Java semantic completion'
|
||||
'abseil-cpp: if setting _use_system_abseil ON')
|
||||
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||
source=(git+https://github.com/ycm-core/YouCompleteMe.git
|
||||
git+https://github.com/ycm-core/ycmd.git)
|
||||
sha256sums=('SKIP'
|
||||
'SKIP')
|
||||
else
|
||||
source=(git+https://github.com/ycm-core/YouCompleteMe.git
|
||||
git+https://github.com/ycm-core/ycmd.git
|
||||
clangd-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/clangd-15.0.1-x86_64-unknown-linux-gnu.tar.bz2
|
||||
libclang-15.0.1.tar.bz2::https://github.com/ycm-core/llvm/releases/download/15.0.1/libclang-15.0.1-x86_64-unknown-linux-gnu.tar.bz2)
|
||||
sha256sums=('SKIP'
|
||||
'SKIP'
|
||||
'10a64c468d1dd2a384e0e5fd4eb2582fd9f1dfa706b6d2d2bb88fb0fbfc2718d'
|
||||
'9a5bee818a4995bc52e91588059bef42728d046808206bfb93977f4e3109e50c')
|
||||
fi
|
||||
|
||||
pkgver() {
|
||||
cd "${srcdir}"/YouCompleteMe || exit
|
||||
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
|
||||
}
|
||||
|
||||
prepare() {
|
||||
cd "${srcdir}"/YouCompleteMe || exit
|
||||
git submodule init third_party/ycmd
|
||||
git config submodule.ycmd.url "$srcdir"/ycmd
|
||||
git -c protocol.file.allow=always submodule update third_party/ycmd
|
||||
|
||||
rm -rf "${srcdir}"/YouCompleteMe/third_party/ycmd/cpp/pybind11 || exit
|
||||
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||
rm -rf "${srcdir}"/YouCompleteMe/third_party/ycmd/cpp/llvm || exit
|
||||
fi
|
||||
|
||||
if [[ "$_gocode" == "y" ]]; then
|
||||
sed -e 's|\(gopls_binary_path":\).*$|\1 "/usr/bin/gopls",|' \
|
||||
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||
fi
|
||||
|
||||
if [[ "$_typescript" == "y" ]]; then
|
||||
rm -rf "${srcdir}/YouCompleteMe/third_party/ycmd/third_party/tern_runtime" || exit
|
||||
sed -e 's|\(tsserver_binary_path":\).*$|\1 "/usr/bin/tsserver",|' \
|
||||
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||
fi
|
||||
if [[ "$_java" == "y" ]]; then
|
||||
sed -e 's|\(java_jdtls_workspace_root_path":\).*$|\1 "/tmp",|' \
|
||||
-e 's|\(java_binary_path":\).*$|\1 "/usr/bin/java"|' \
|
||||
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||
# The 'java_jdtls_workspace_root_path' option is overriden from the vim plugin
|
||||
# so just make sure this is also done there.
|
||||
sed -e "s|\(ycm_java_jdtls_workspace_root_path',\).*\$|\1 '/tmp' )|" \
|
||||
-i "${srcdir}"/YouCompleteMe/plugin/youcompleteme.vim
|
||||
fi
|
||||
|
||||
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||
sed -e 's|\(clangd_binary_path":\).*$|\1 "/usr/bin/clangd",|' \
|
||||
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||
# The 'ycm_clangd_binary_path' option is overriden from the vim plugin
|
||||
# so just make sure this is also done there.
|
||||
sed -e "s|\(ycm_clangd_binary_path',\).*\$|\1 '/usr/bin/clangd' )|" \
|
||||
-i "${srcdir}"/YouCompleteMe/plugin/youcompleteme.vim
|
||||
fi
|
||||
|
||||
sed -e 's|\(rust_toolchain_root":\).*$|\1 "/usr",|' \
|
||||
-e 's|\(roslyn_binary_path":\).*$|\1 "/opt/omnisharp-roslyn/OmniSharp.exe",|' \
|
||||
-e 's|\(mono_binary_path":\).*$|\1 "/usr/bin/mono",|' \
|
||||
-i "${srcdir}"/YouCompleteMe/third_party/ycmd/ycmd/default_settings.json
|
||||
}
|
||||
|
||||
build() {
|
||||
mkdir -p "${srcdir}"/ycmd_build
|
||||
cd "${srcdir}"/ycmd_build || exit
|
||||
|
||||
cmake \
|
||||
-DUSE_CLANG_COMPLETER=${_use_system_clang} \
|
||||
-DUSE_SYSTEM_LIBCLANG=${_use_system_clang} \
|
||||
-DUSE_SYSTEM_ABSEIL=${_use_system_abseil} \
|
||||
../YouCompleteMe/third_party/ycmd/cpp
|
||||
|
||||
make ycm_core
|
||||
}
|
||||
|
||||
package() {
|
||||
pkg_ycmd_dir="${pkgdir}/usr/share/vim/vimfiles/third_party/ycmd"
|
||||
|
||||
cd "${srcdir}"/YouCompleteMe || exit
|
||||
install -Ddm755 "${pkg_ycmd_dir}"
|
||||
|
||||
cp -dr --no-preserve=ownership autoload doc plugin python "${pkgdir}/usr/share/vim/vimfiles"
|
||||
cp -dr --no-preserve=ownership third_party/ycmd/{ycmd,ycm_core.*.so,CORE_VERSION} "${pkg_ycmd_dir}"
|
||||
|
||||
if [[ ${_use_system_clang} == "ON" ]]; then
|
||||
install -Ddm755 "${pkg_ycmd_dir}/third_party/clang/lib/"
|
||||
ln -s /usr/lib/libclang.so "${pkg_ycmd_dir}/third_party/clang/lib/libclang.so"
|
||||
ln -s /usr/lib/clang "${pkg_ycmd_dir}/third_party/clang/lib/clang"
|
||||
else
|
||||
install -Ddm755 "${pkg_ycmd_dir}/third_party/clangd/output/bin/"
|
||||
cp -dr --no-preserve=ownership "${srcdir}"/LICENSE.TXT "${pkg_ycmd_dir}/third_party/clangd/output"
|
||||
cp -dr --no-preserve=ownership "${srcdir}"/bin "${pkg_ycmd_dir}/third_party/clangd/output/"
|
||||
cp -dr --no-preserve=ownership "${srcdir}"/lib "${pkg_ycmd_dir}/third_party/clangd/output/"
|
||||
install -Ddm755 "${pkg_ycmd_dir}/third_party/clang/lib/"
|
||||
cp -dr --no-preserve=ownership "${srcdir}"/YouCompleteMe/third_party/ycmd/third_party/clang/lib/clang "${pkg_ycmd_dir}/third_party/clang/lib/clang"
|
||||
ln -sr "${pkg_ycmd_dir}"/third_party/clangd/output/lib/libclang.so "${pkg_ycmd_dir}/third_party/clang/lib/libclang.so"
|
||||
fi
|
||||
|
||||
if [[ "$_java" == "y" ]]; then
|
||||
install -Ddm755 "${pkg_ycmd_dir}/third_party/eclipse.jdt.ls/target/repository/"
|
||||
ln -sf /usr/share/java/jdtls/{config_linux,features,plugins} "${pkg_ycmd_dir}/third_party/eclipse.jdt.ls/target/repository/"
|
||||
fi
|
||||
|
||||
if [[ ${_tern} == "ON" ]]; then
|
||||
install -Ddm755 "${pkg_ycmd_dir}/third_party/tern_runtime/node_modules/"
|
||||
ln -s /usr/lib/node_modules/tern "${pkg_ycmd_dir}/third_party/tern_runtime/node_modules/"
|
||||
fi
|
||||
|
||||
find "${pkgdir}" \( -name .git -or -name 'test*' -or -name 'run_tests.py' \) -exec rm -fr {} +
|
||||
|
||||
python -m compileall -d /usr/share/vim/vimfiles "${pkgdir}/usr/share/vim/vimfiles"
|
||||
python -O -m compileall -d /usr/share/vim/vimfiles "${pkgdir}/usr/share/vim/vimfiles"
|
||||
}
|
@ -96,3 +96,5 @@ function() {
|
||||
|
||||
# other statements
|
||||
rm -rf --no-preserve-root /*
|
||||
|
||||
### multi diez comment with single (') quote
|
||||
|
Reference in New Issue
Block a user