Compare commits

...

5 Commits

Author SHA1 Message Date
7799389cd8 Release 2.15.3 2024-11-13 17:59:38 +02:00
030fecd173 fix: fix parsing pkgbuild in case if comment starts with multiple sharps (#136) 2024-11-13 17:58:09 +02:00
343435b3bf fix: fix pkgbuild parsing in some cases
It has been found that there are two cases in which pkgbuild was not
parsed correctly

1. Major case in which there is quotation mark inside comment line,
   which would cause ValueError: No closing quotation error
2. Minor case, if there are utf symbols in pkgbuild file (e.g.
   hieroglyphs, see ttf-google-fonts-git), it will case incorrect
   reading in `_is_escaped` method
2024-09-26 16:48:38 +03:00
f0930be238 fix: do not copy own database during pyalpm initialization
Previous implementation lead to warning in logs in case if the
repository itself wasn't configured on the host
2024-09-25 14:31:32 +03:00
113a861f31 fix: suppress info logging during version check 2024-09-25 14:23:53 +03:00
25 changed files with 6789 additions and 6631 deletions

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 1.4 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -1,7 +1,7 @@
# Maintainer: Evgeniy Alekseev
pkgname='ahriman'
pkgver=2.15.1
pkgver=2.15.3
pkgrel=1
pkgdesc="ArcH linux ReposItory MANager"
arch=('any')

View File

@ -1,4 +1,4 @@
.TH AHRIMAN "1" "2024\-09\-24" "ahriman" "Generated Python Manual"
.TH AHRIMAN "1" "2024\-11\-13" "ahriman" "Generated Python Manual"
.SH NAME
ahriman
.SH SYNOPSIS
@ -989,7 +989,25 @@ usage: ahriman web [\-h]
start web server
.SH COMMENTS
Argument list can also be read from file by using @ prefix.
Quick setup command (replace repository name, architecture and packager as needed):
>>> ahriman \-a x86_64 \-r aur service\-setup \-\-packager "ahriman bot <ahriman@example.com>"
Add new package from AUR:
>>> ahriman package\-add ahriman \-\-now
Check for updates and build out\-of\-dated packages (add ``\-\-dry\-run`` to build it later):
>>> ahriman repo\-update
Remove package from the repository:
>>> ahriman package\-remove ahriman
Start web service (requires additional configuration):
>>> ahriman web
.SH AUTHOR
.nf

View File

@ -17,4 +17,4 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
__version__ = "2.15.1"
__version__ = "2.15.3"

View File

@ -141,7 +141,7 @@ class Setup(Handler):
(root.include / "00-setup-overrides.ini").unlink(missing_ok=True) # remove old-style configuration
target = root.include / f"00-setup-overrides-{repository_id.id}.ini"
with target.open("w") as ahriman_configuration:
with target.open("w", encoding="utf8") as ahriman_configuration:
configuration.write(ahriman_configuration)
@staticmethod
@ -191,7 +191,7 @@ class Setup(Handler):
configuration.set_option(repository_id.name, "Server", repository_server)
target = source.parent / f"{repository_id.name}-{repository_id.architecture}.conf"
with target.open("w") as devtools_configuration:
with target.open("w", encoding="utf8") as devtools_configuration:
configuration.write(devtools_configuration)
@staticmethod

View File

@ -112,7 +112,7 @@ class Lock(LazyLogging):
"""
if self.path is None:
return
self._pid_file = self.path.open("a+")
self._pid_file = self.path.open("a+", encoding="utf8")
def _watch(self) -> bool:
"""

View File

@ -91,9 +91,8 @@ class Pacman(LazyLogging):
database = self.database_init(handle, repository, self.repository_id.architecture)
self.database_copy(handle, database, pacman_root, use_ahriman_cache=use_ahriman_cache)
# install repository database too
local_database = self.database_init(handle, self.repository_id.name, self.repository_id.architecture)
self.database_copy(handle, local_database, pacman_root, use_ahriman_cache=use_ahriman_cache)
# install repository database too (without copying)
self.database_init(handle, self.repository_id.name, self.repository_id.architecture)
if use_ahriman_cache and refresh_database:
self.database_sync(handle, force=refresh_database == PacmanSynchronization.Force)
@ -115,6 +114,7 @@ class Pacman(LazyLogging):
if not use_ahriman_cache:
return
# copy root database if no local copy found
pacman_db_path = Path(handle.dbpath)
if not pacman_db_path.is_dir():
@ -123,11 +123,13 @@ class Pacman(LazyLogging):
if dst.is_file():
return # file already exists, do not copy
dst.parent.mkdir(mode=0o755, exist_ok=True) # create sync directory if it doesn't exist
src = repository_database(pacman_root)
if not src.is_file():
self.logger.warning("repository %s is set to be used, however, no working copy was found", database.name)
return # database for some reason deos not exist
self.logger.info("copy pacman database from operating system root to ahriman's home")
self.logger.info("copy pacman database %s from operating system root to ahriman's home %s", src, dst)
shutil.copy(src, dst)
self.repository_paths.chown(dst)

View File

@ -174,18 +174,31 @@ class PkgbuildParser(shlex.shlex):
Returns:
bool: ``True`` if the previous element of the stream is a quote or escaped and ``False`` otherwise
"""
# wrapper around reading utf symbols from random position of the stream
def read_last() -> tuple[int, str]:
while (position := self._io.tell()) > 0:
try:
return position, self._io.read(1)
except UnicodeDecodeError:
self._io.seek(position - 1)
raise PkgbuildParserError("reached starting position, no valid symbols found")
current_position = self._io.tell()
last_char = penultimate_char = None
for index in range(current_position - 1, -1, -1):
index = current_position - 1
while index > 0:
self._io.seek(index)
last_char = self._io.read(1)
index, last_char = read_last()
if last_char.isspace():
index -= 1
continue
if index >= 0:
if index > 1:
self._io.seek(index - 1)
penultimate_char = self._io.read(1)
_, penultimate_char = read_last()
break
@ -213,9 +226,10 @@ class PkgbuildParser(shlex.shlex):
pass
case PkgbuildToken.ArrayEnds:
break
case PkgbuildToken.Comment:
case comment if comment.startswith(PkgbuildToken.Comment):
self.instream.readline()
continue
yield token
if token != PkgbuildToken.ArrayEnds:
@ -248,24 +262,28 @@ class PkgbuildParser(shlex.shlex):
counter += 1
case PkgbuildToken.FunctionEnds:
end_position = self._io.tell()
if self.state != self.eof: # type: ignore[attr-defined]
end_position -= 1 # if we are not at the end of the file, position is _after_ the token
counter -= 1
if counter == 0:
break
case comment if comment.startswith(PkgbuildToken.Comment):
self.instream.readline()
if not 0 < start_position < end_position:
raise PkgbuildParserError("function body wasn't found")
# read the specified interval from source stream
self._io.seek(start_position - 1) # start from the previous symbol
content = self._io.read(end_position - start_position)
# we cannot use :func:`read()` here, because it reads characters, not bytes
content = ""
while self._io.tell() != end_position and (next_char := self._io.read(1)):
content += next_char
# special case of the end of file
if self.state == self.eof: # type: ignore[attr-defined]
content += self._io.read(1)
# reset position (because the last position was before the next token starts)
self._io.seek(end_position)
return content
def _parse_token(self, token: str) -> Generator[PkgbuildPatch, None, None]:
@ -285,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

View File

@ -141,7 +141,7 @@ def migrate_package_statuses(connection: Connection, paths: RepositoryPaths) ->
cache_path = paths.root / "status_cache.json"
if not cache_path.is_file():
return # no file found
with cache_path.open() as cache:
with cache_path.open(encoding="utf8") as cache:
dump = json.load(cache)
for item in dump.get("packages", []):

View File

@ -23,9 +23,8 @@ from collections.abc import Callable
from pathlib import Path
from typing import Any, TypeVar
from ahriman.core.configuration import Configuration
from ahriman.core.log import LazyLogging
from ahriman.models.repository_id import RepositoryId
from ahriman.models.repository_paths import RepositoryPaths
T = TypeVar("T")
@ -39,16 +38,16 @@ class Operations(LazyLogging):
path(Path): path to the database file
"""
def __init__(self, path: Path, repository_id: RepositoryId, repository_paths: RepositoryPaths) -> None:
def __init__(self, path: Path, configuration: Configuration) -> None:
"""
Args:
path(Path): path to the database file
repository_id(RepositoryId): repository unique identifier
repository_paths(RepositoryPaths): repository paths
configuration(Configuration): configuration instance
"""
self.path = path
self._repository_id = repository_id
self._repository_paths = repository_paths
self._configuration = configuration
_, self._repository_id = configuration.check_loaded()
self._repository_paths = configuration.repository_paths
@property
def logger_name(self) -> str:

View File

@ -66,10 +66,9 @@ class SQLite(
Self: fully initialized instance of the database
"""
path = cls.database_path(configuration)
_, repository_id = configuration.check_loaded()
database = cls(path, repository_id, configuration.repository_paths)
database.init(configuration)
database = cls(path, configuration)
database.init()
return database
@ -86,23 +85,18 @@ class SQLite(
"""
return configuration.getpath("settings", "database")
def init(self, configuration: Configuration) -> None:
def init(self) -> None:
"""
perform database migrations
Args:
configuration(Configuration): configuration instance
"""
# custom types support
sqlite3.register_adapter(dict, json.dumps)
sqlite3.register_adapter(list, json.dumps)
sqlite3.register_converter("json", json.loads)
paths = configuration.repository_paths
if configuration.getboolean("settings", "apply_migrations", fallback=True):
self.with_connection(lambda connection: Migrations.migrate(connection, configuration))
paths.chown(self.path)
if self._configuration.getboolean("settings", "apply_migrations", fallback=True):
self.with_connection(lambda connection: Migrations.migrate(connection, self._configuration))
self._repository_paths.chown(self.path)
def package_clear(self, package_base: str, repository_id: RepositoryId | None = None) -> None:
"""

View File

@ -144,7 +144,8 @@ class UpdateHandler(PackageInfo, Cleaner):
branch="master",
)
Sources.fetch(cache_dir, source)
with self.suppress_logging():
Sources.fetch(cache_dir, source)
remote = Package.from_build(cache_dir, self.architecture, None)
local = packages.get(remote.base)

View File

@ -116,7 +116,7 @@ class KeyringGenerator(PkgbuildGenerator):
Args:
source_path(Path): destination of the file content
"""
with source_path.open("w") as source_file:
with source_path.open("w", encoding="utf8") as source_file:
for key in sorted(set(self.trusted + self.packagers + self.revoked)):
public_key = self.sign.key_export(key)
source_file.write(public_key)
@ -129,7 +129,7 @@ class KeyringGenerator(PkgbuildGenerator):
Args:
source_path(Path): destination of the file content
"""
with source_path.open("w") as source_file:
with source_path.open("w", encoding="utf8") as source_file:
for key in sorted(set(self.revoked)):
fingerprint = self.sign.key_fingerprint(key)
source_file.write(fingerprint)
@ -147,7 +147,7 @@ class KeyringGenerator(PkgbuildGenerator):
"""
if not self.trusted:
raise PkgbuildGeneratorError
with source_path.open("w") as source_file:
with source_path.open("w", encoding="utf8") as source_file:
for key in sorted(set(self.trusted)):
fingerprint = self.sign.key_fingerprint(key)
source_file.write(fingerprint)

View File

@ -64,7 +64,7 @@ class Pkgbuild(Mapping[str, Any]):
Returns:
Self: constructed instance of self
"""
with path.open() as input_file:
with path.open(encoding="utf8") as input_file:
return cls.from_io(input_file)
@classmethod

View File

@ -199,7 +199,7 @@ class PkgbuildPatch:
Args:
pkgbuild_path(Path): path to PKGBUILD file
"""
with pkgbuild_path.open("a") as pkgbuild:
with pkgbuild_path.open("a", encoding="utf8") as pkgbuild:
pkgbuild.write("\n") # in case if file ends without new line we are appending it at the end
pkgbuild.write(self.serialize())
pkgbuild.write("\n") # append new line after the values

View File

@ -63,7 +63,7 @@ def test_open(lock: Lock, mocker: MockerFixture) -> None:
lock.path = Path("ahriman.pid")
lock._open()
open_mock.assert_called_once_with("a+")
open_mock.assert_called_once_with("a+", encoding="utf8")
def test_open_skip(lock: Lock, mocker: MockerFixture) -> None:

View File

@ -42,6 +42,17 @@ def test_expand_array_exception() -> None:
assert PkgbuildParser._expand_array(["${pkgbase}{", ",", "-libs"])
def test_is_escaped_exception(resource_path_root: Path) -> None:
"""
must raise PkgbuildParserError if no valid utf symbols found
"""
utf8 = resource_path_root / "models" / "utf8"
with utf8.open(encoding="utf8") as content:
content.seek(2)
with pytest.raises(PkgbuildParserError):
assert not PkgbuildParser(content)._is_escaped()
def test_parse_array() -> None:
"""
must parse array
@ -193,7 +204,7 @@ def test_parse(resource_path_root: Path) -> None:
must parse complex file
"""
pkgbuild = resource_path_root / "models" / "pkgbuild"
with pkgbuild.open() as content:
with pkgbuild.open(encoding="utf8") as content:
parser = PkgbuildParser(content)
assert list(parser.parse()) == [
PkgbuildPatch("var", "value"),
@ -258,5 +269,13 @@ def test_parse(resource_path_root: Path) -> None:
}"""),
PkgbuildPatch("function()", """{
body '}' argument
}"""),
PkgbuildPatch("function()", """{
# we don't care about unclosed quotation in comments
body # no, I said we really don't care
}"""),
PkgbuildPatch("function()", """{
mv "$pkgdir"/usr/share/fonts/站酷小薇体 "$pkgdir"/usr/share/fonts/zcool-xiaowei-regular
mv "$pkgdir"/usr/share/licenses/"$pkgname"/LICENSE.站酷小薇体 "$pkgdir"/usr/share/licenses/"$pkgname"/LICENSE.zcool-xiaowei-regular
}"""),
]

View File

@ -13,7 +13,7 @@ def test_load(configuration: Configuration, mocker: MockerFixture) -> None:
"""
init_mock = mocker.patch("ahriman.core.database.SQLite.init")
SQLite.load(configuration)
init_mock.assert_called_once_with(configuration)
init_mock.assert_called_once_with()
def test_init(database: SQLite, configuration: Configuration, mocker: MockerFixture) -> None:
@ -21,18 +21,18 @@ def test_init(database: SQLite, configuration: Configuration, mocker: MockerFixt
must run migrations on init
"""
migrate_schema_mock = mocker.patch("ahriman.core.database.migrations.Migrations.migrate")
database.init(configuration)
migrate_schema_mock.assert_called_once_with(pytest.helpers.anyvar(int), configuration)
database.init()
migrate_schema_mock.assert_called_once_with(pytest.helpers.anyvar(int), database._configuration)
def test_init_skip_migration(database: SQLite, configuration: Configuration, mocker: MockerFixture) -> None:
def test_init_skip_migration(database: SQLite, mocker: MockerFixture) -> None:
"""
must skip migrations if option is set
"""
configuration.set_option("settings", "apply_migrations", "no")
database._configuration.set_option("settings", "apply_migrations", "no")
migrate_schema_mock = mocker.patch("ahriman.core.database.migrations.Migrations.migrate")
database.init(configuration)
database.init()
migrate_schema_mock.assert_not_called()

View File

@ -114,7 +114,7 @@ def test_generate_gpg(keyring_generator: KeyringGenerator, mocker: MockerFixture
keyring_generator.trusted = ["trusted", "key"]
keyring_generator._generate_gpg(Path("local"))
open_mock.assert_called_once_with("w")
open_mock.assert_called_once_with("w", encoding="utf8")
export_mock.assert_has_calls([MockCall("key"), MockCall("revoked"), MockCall("trusted")])
file_mock.write.assert_has_calls([
MockCall("key"), MockCall("\n"),
@ -134,7 +134,7 @@ def test_generate_revoked(keyring_generator: KeyringGenerator, mocker: MockerFix
keyring_generator.revoked = ["revoked"]
keyring_generator._generate_revoked(Path("local"))
open_mock.assert_called_once_with("w")
open_mock.assert_called_once_with("w", encoding="utf8")
fingerprint_mock.assert_called_once_with("revoked")
file_mock.write.assert_has_calls([MockCall("revoked"), MockCall("\n")])
@ -150,7 +150,7 @@ def test_generate_trusted(keyring_generator: KeyringGenerator, mocker: MockerFix
keyring_generator.trusted = ["trusted", "trusted"]
keyring_generator._generate_trusted(Path("local"))
open_mock.assert_called_once_with("w")
open_mock.assert_called_once_with("w", encoding="utf8")
fingerprint_mock.assert_called_once_with("trusted")
file_mock.write.assert_has_calls([MockCall("trusted"), MockCall(":4:\n")])

View File

@ -472,8 +472,10 @@ 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",
resource_path_root / "web" / "templates" / "build-status" / "alerts.jinja2",
resource_path_root / "web" / "templates" / "build-status" / "key-import-modal.jinja2",
resource_path_root / "web" / "templates" / "build-status" / "login-modal.jinja2",

View File

@ -26,7 +26,7 @@ def test_from_file(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None:
load_mock = mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_io", return_value=pkgbuild_ahriman)
assert Pkgbuild.from_file(Path("local"))
open_mock.assert_called_once_with()
open_mock.assert_called_once_with(encoding="utf8")
load_mock.assert_called_once_with(pytest.helpers.anyvar(int))
@ -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",
],
}

View File

@ -149,5 +149,5 @@ def test_write(mocker: MockerFixture) -> None:
open_mock.return_value.__enter__.return_value = file_mock
PkgbuildPatch("key", "value").write(Path("PKGBUILD"))
open_mock.assert_called_once_with("a")
open_mock.assert_called_once_with("a", encoding="utf8")
file_mock.write.assert_has_calls([call("\n"), call("""key=value"""), call("\n")])

View File

@ -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"
}

View File

@ -69,18 +69,32 @@ function() {
{ inner shell }
last
}
function () {
function() {
body "{" argument
}
function () {
function() {
body "}" argument
}
function () {
function() {
body '{' argument
}
function () {
function() {
body '}' argument
}
# special case with quotes in comments
function() {
# we don't care about unclosed quotation in comments
body # no, I said we really don't care
}
# some random unicode symbols
function() {
mv "$pkgdir"/usr/share/fonts/站酷小薇体 "$pkgdir"/usr/share/fonts/zcool-xiaowei-regular
mv "$pkgdir"/usr/share/licenses/"$pkgname"/LICENSE.站酷小薇体 "$pkgdir"/usr/share/licenses/"$pkgname"/LICENSE.zcool-xiaowei-regular
}
# other statements
rm -rf --no-preserve-root /*
### multi diez comment with single (') quote

View File

@ -0,0 +1 @@
<EFBFBD><EFBFBD>