450 lines
16 KiB
RPMSpec
450 lines
16 KiB
RPMSpec
# Currently, ty is developed together with ruff in
|
||
# https://github.com/astral-sh/ruff. The repository
|
||
# https://github.com/astral-sh/ty contains only the ty-specific bits, and
|
||
# depends on the ruff repository as a git submodule. We therefore *must*
|
||
# “bundle” ruff, and this spec file is based closely on (and mirrors the
|
||
# structure of) the one for ruff.
|
||
|
||
%bcond check 1
|
||
|
||
Name: ty
|
||
Version: 0.0.78
|
||
# The ty package has a permanent exception to the Updates Policy in Fedora,
|
||
# so it can be updated in stable releases across SemVer boundaries (subject to
|
||
# good judgement and actual compatibility of any reverse dependencies). See
|
||
# https://docs.fedoraproject.org/en-US/fesco/Updates_Policy/#_other_packages,
|
||
# https://pagure.io/fesco/issue/3564.
|
||
Release: %autorelease
|
||
Summary: Extremely fast Python type checker and language server
|
||
|
||
# The license of the ty project is MIT. Other source licenses come from ruff.
|
||
# The comments below will generally be synchronized with those in the ruff spec
|
||
# file.
|
||
#
|
||
# The license of the ruff project is MIT, except:
|
||
#
|
||
# As described in https://github.com/astral-sh/ruff/pull/20222, the README
|
||
# lists projects whose rules ruff has (re)implemented but from which ruff does
|
||
# not otherwise reuse or adapt source code. We don’t consider those to be
|
||
# bundled dependencies, and we don’t consider their licenses to contribute to
|
||
# the licenses of the binary RPMs.
|
||
#
|
||
# Meanwhile, LICENSE documents projects from which parts of ruff are derived,
|
||
# e.g. by copying and adapting source code. In general, we can’t always readily
|
||
# identify precisely which source files are derived from each of these upstream
|
||
# projects, and it doesn’t make sense to treat them as bundled or vendored
|
||
# dependencies. However, we do need to account for their licenses.
|
||
#
|
||
# MIT (same as ruff itself):
|
||
# - autoflake
|
||
# - autotyping
|
||
# - flake8
|
||
# - flake8-eradicate
|
||
# - flake8-pyi
|
||
# - flake8-simplify
|
||
# - isort
|
||
# - pygrep-hooks
|
||
# - pycodestyle
|
||
# - pydocstyle
|
||
# - pyflakes
|
||
# - Pyright
|
||
# - pyupgrade
|
||
# - rome/tools
|
||
# - RustPython
|
||
# - rust-analyzer/text-size
|
||
#
|
||
# =====
|
||
#
|
||
# Besides the above projects mentioned in LICENSE, the following vendored,
|
||
# forked, or derived code is present, either directly in the ruff source
|
||
# archive or as additional sources corresponding to git dependencies.
|
||
#
|
||
# Apache-2.0 AND MIT:
|
||
# - crates/ty_vendored/vendor/typeshed/ is a bundled snapshot of
|
||
# https://github.com/python/typeshed at a commit hash listed in
|
||
# ruff/crates/ty_vendored/vendor/typeshed/source_commit.txt; license text
|
||
# is in crates/ty_vendored/vendor/typeshed/LICENSE
|
||
#
|
||
# Within the typeshed snapshot, the docstring of
|
||
# crates/ty_vendored/vendor/typeshed/stdlib/ast.pyi cites the Python-2.0.1
|
||
# license of the ast module from the Python library. We feel that this
|
||
# type-stub file probably doesn’t contain enough of the original Python
|
||
# source for the license to apply. If we’re wrong, then SourceLicense and
|
||
# License should gain a Python-2.0.1 term.
|
||
#
|
||
# Apache-2.0 OR MIT:
|
||
# - crates/ruff_annotate_snippets/ is a fork of the annotate-snippets crate
|
||
#
|
||
# =====
|
||
#
|
||
# A few other source files carry their own licenses but do not fit into the
|
||
# above categories.
|
||
#
|
||
# Apache-2.0:
|
||
# - crates/ruff_server/resources/test/fixtures/tensorflow_test_notebook.ipynb
|
||
# comes from TensorFlow, and some of its content also appears in
|
||
# crates/ruff_server/tests/notebook.rs and in the snapshots
|
||
# crates/ruff_server/tests/snapshots/notebook__changed_notebook.snap and
|
||
# crates/ruff_server/tests/snapshots/notebook__initial_notebook.snap; none
|
||
# of these should contribute to the licenses of the binary RPMs, since they
|
||
# are only for testing
|
||
#
|
||
# Apache-2.0 OR MIT:
|
||
# - .github/workflows/release.yml (autogenerated by dist,
|
||
# https://github.com/astral-sh/cargo-dist; does not contribute to the
|
||
# licenses of the binary RPMs, since it is only for CI)
|
||
#
|
||
# MIT:
|
||
# - playground/shared/src/Icons.tsx contains icons from the VS code icon set,
|
||
# https://github.com/microsoft/vscode-icons/; we do not package the
|
||
# in-browser playground, available at https://play.ruff.rs/, so this file
|
||
# does not contribute to the licenses of the binary RPMs
|
||
SourceLicense: %{shrink:
|
||
MIT AND
|
||
Apache-2.0 AND
|
||
(Apache-2.0 OR MIT)
|
||
}
|
||
|
||
# Rust crates compiled into the executable contribute additional license terms.
|
||
# To obtain the following list of licenses, build the package and note the
|
||
# output of %%{cargo_license_summary}. This should automatically include the
|
||
# licenses of the crates that were bundled as additional Sources.
|
||
#
|
||
# (MIT OR Apache-2.0) AND Unicode-3.0
|
||
# (MIT OR Apache-2.0) AND Unicode-DFS-2016
|
||
# Apache-2.0
|
||
# Apache-2.0 OR BSD-2-Clause
|
||
# Apache-2.0 OR BSL-1.0
|
||
# Apache-2.0 OR MIT
|
||
# Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT
|
||
# CC0-1.0
|
||
# ISC
|
||
# MIT
|
||
# MIT AND (MIT AND PSF-2.0)
|
||
# MIT AND BSD-3-Clause
|
||
# MIT OR Apache-2.0
|
||
# MIT OR Apache-2.0 OR Zlib
|
||
# MIT OR BSD-3-Clause
|
||
# MIT-0 OR Apache-2.0
|
||
# MPL-2.0
|
||
# Unicode-3.0
|
||
# Unlicense OR MIT
|
||
# WTFPL
|
||
# Zlib
|
||
# Zlib OR Apache-2.0 OR MIT
|
||
License: %{shrink:
|
||
MIT AND
|
||
Apache-2.0 AND
|
||
(Apache-2.0 OR BSD-2-Clause) AND
|
||
(Apache-2.0 OR BSL-1.0) AND
|
||
(Apache-2.0 OR MIT) AND
|
||
(Apache-2.0 OR MIT OR Zlib) AND
|
||
(Apache-2.0 OR MIT-0) AND
|
||
(Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT) AND
|
||
BSD-3-Clause AND
|
||
(BSD-3-Clause OR MIT) AND
|
||
CC0-1.0 AND
|
||
ISC AND
|
||
(MIT OR Unlicense) AND
|
||
MPL-2.0 AND
|
||
PSF-2.0 AND
|
||
Unicode-3.0 AND
|
||
Unicode-DFS-2016 AND
|
||
WTFPL AND
|
||
Zlib
|
||
}
|
||
|
||
URL: https://github.com/astral-sh/ty
|
||
Source: %{url}/archive/%{version}/ty-%{version}.tar.gz
|
||
|
||
# Regarding bundling ruff, see the comments at the beginning of the spec file.
|
||
%global ruff_git https://github.com/astral-sh/ruff
|
||
%global ruff_rev 827326f12bbbfc1c9cc52f6effa4033bc84ce66a
|
||
%global ruff_baseversion 0.16.6
|
||
%global ruff_snapdate 20260902
|
||
Source100: %{ruff_git}/archive/%{ruff_rev}/ruff-%{ruff_rev}.tar.gz
|
||
|
||
# Get this from ruff/crates/ty_vendored/vendor/typeshed/source_commit.txt.
|
||
%global typeshed_rev cf09d2a4d7614f648e9109dce609887499a7c6ee
|
||
# The typeshed project as a whole has never been versioned.
|
||
%global typeshed_baseversion 0
|
||
# Inspect https://github.com/python/typeshed/commit/%%{typeshed_rev}.
|
||
%global typeshed_snapdate 20260831
|
||
|
||
# Downstream patch: always find the system-wide ty executable
|
||
#
|
||
# The following issue is for uv, but the situation is exactly the same.
|
||
#
|
||
# “Should uv.find_uv_bin() be able to find /usr/bin/uv?”
|
||
# https://github.com/astral-sh/uv/issues/4451
|
||
Patch: 0001-Downstream-patch-always-find-the-system-wide-ty-exec.patch
|
||
|
||
# Downstream patches for ruff, copied from the ruff package
|
||
# * ignore tests in vendored annotate-snippets that hang indefinitely:
|
||
Patch102: 0002-ignore-vendored-annotate-snippets-tests-that-hang-in.patch
|
||
|
||
BuildSystem: pyproject
|
||
BuildOption(install): --assert-license ty
|
||
|
||
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
|
||
ExcludeArch: %{ix86}
|
||
|
||
# Memory exhaustion can occur. Increase as needed.
|
||
%global _smp_tasksize_proc 16384
|
||
|
||
BuildRequires: cargo-rpm-macros
|
||
BuildRequires: rust2rpm-helper
|
||
BuildRequires: tomcli
|
||
|
||
# See the notes about Source100.
|
||
%global ruff_snapinfo %{ruff_snapdate}git%{sub %{ruff_rev} 1 7}
|
||
%global ruff_version %{ruff_baseversion}^%{ruff_snapinfo}
|
||
Provides: bundled(ruff) = %{ruff_version}
|
||
|
||
# This is not versioned or released as a whole, and it is normal for
|
||
# type-checkers to vendor it. See
|
||
# https://typing.python.org/en/latest/spec/distributing.html#the-typeshed-project.
|
||
%global typeshed_snapinfo %{typeshed_snapdate}git%{sub %{typeshed_rev} 1 7}
|
||
%global typeshed_version %{typeshed_baseversion}^%{typeshed_snapinfo}
|
||
Provides: bundled(typeshed) = %{typeshed_version}
|
||
|
||
# Forked from annotate-snippets upstream at some point after v0.11.5:
|
||
# https://github.com/astral-sh/ruff/pull/15359
|
||
#
|
||
# In ruff/crates/ruff_annotate_snippets/README.md, upstream writes:
|
||
#
|
||
# This is a fork of the [`annotate-snippets` crate]. The principle motivation
|
||
# for this fork, at the time of writing, is [issue #167]. Specifically, we
|
||
# wanted to upgrade our version of `annotate-snippets`, but do so _without_
|
||
# changing our diagnostic message format.
|
||
#
|
||
# This copy of `annotate-snippets` is basically identical to upstream, but
|
||
# with an extra `Level::None` variant that permits skipping over a new
|
||
# non-optional header emitted by `annotate-snippets`.
|
||
#
|
||
# More generally, it seems plausible that we may want to tweak other aspects
|
||
# of the output format in the future, so it might make sense to stick with
|
||
# our own copy so that we can be masters of our own destiny.
|
||
#
|
||
# [issue #167]: https://github.com/rust-lang/annotate-snippets-rs/issues/167
|
||
# [`annotate-snippets` crate]: https://github.com/rust-lang/annotate-snippets-rs
|
||
Provides: bundled(crate(annotate-snippets)) = 0.11.5
|
||
|
||
%global common_description %{expand:
|
||
An extremely fast Python type checker and language server, written in Rust.}
|
||
|
||
%description %{common_description}
|
||
|
||
|
||
%package -n python3-ty
|
||
Summary: Importable Python module for ty
|
||
|
||
BuildArch: noarch
|
||
|
||
Requires: ty = %{version}-%{release}
|
||
|
||
%description -n python3-ty %{common_description}
|
||
|
||
This package provides an importable Python module for ty.
|
||
|
||
|
||
%prep
|
||
%autosetup -N
|
||
%autopatch -p1 -M99
|
||
|
||
%cargo_prep
|
||
|
||
# See comments above Source100:
|
||
%setup -q -T -D -b 100 -n ty-%{version}
|
||
# Replace the empty directory corresponding to a git submodule with the
|
||
# extracted ruff source tree.
|
||
rmdir ruff
|
||
mv ../ruff-%{ruff_rev} ruff
|
||
pushd ruff
|
||
%autopatch -p1 -m100 -M199
|
||
# We have to adjust this both in the top-level pyproject.toml and in the ruff
|
||
# pyproject.toml. (TODO: Is this really true?)
|
||
tomcli set pyproject.toml false tool.maturin.strip
|
||
%cargo_prep
|
||
popd
|
||
|
||
# Loosen some version bounds. We retain this comment and the following example
|
||
# even when there are currently no dependencies that need to be adjusted.
|
||
#
|
||
# # foocrate
|
||
# # wanted: 0.2.0
|
||
# # currently packaged: 0.1.2
|
||
# # https://bugzilla.redhat.com/show_bug.cgi?id=1234567
|
||
# tomcli set ruff/Cargo.toml str workspace.dependencies.foocrate.version 0.1.2
|
||
|
||
# get-size2
|
||
# wanted: 0.9.0
|
||
# currently packaged: 0.10.0
|
||
# We haven’t suggested this upstream because we know they use renovate with
|
||
# dependency cooldowns, and we expect they will soon update without prompting.
|
||
tomcli set ruff/Cargo.toml str workspace.dependencies.get-size2.version \
|
||
'>=0.9.0, <0.11.0'
|
||
|
||
# tikv-jemallocator
|
||
# wanted: 0.6.0
|
||
# currently packaged: 0.7.0
|
||
# We haven’t suggested this upstream because we know they use renovate with
|
||
# dependency cooldowns, and we expect they will soon update without prompting.
|
||
tomcli set ruff/Cargo.toml str \
|
||
workspace.dependencies.tikv-jemallocator.version '>=0.6.0, <0.8.0'
|
||
|
||
# Collect license files of vendored dependencies in the main source archive
|
||
install -D --preserve-timestamps --mode=0644 \
|
||
--target=LICENSE.bundled/typeshed \
|
||
ruff/crates/ty_vendored/vendor/typeshed/LICENSE
|
||
install -D --preserve-timestamps --mode=0644 \
|
||
--target=LICENSE.bundled/annotate_snippets \
|
||
ruff/crates/ruff_annotate_snippets/LICENSE-*
|
||
|
||
# Patch out foreign (e.g. Windows-only) dependencies. Follow symbolic links so
|
||
# that we also patch the bundled crates we just finished setting up.
|
||
find -L . -type f -name Cargo.toml -print \
|
||
-execdir rust2rpm-helper strip-foreign -o '{}' '{}' ';'
|
||
|
||
# Drop unused subproject crates.
|
||
# binary crate for running micro-benchmarks.
|
||
rm --recursive --verbose ruff/crates/ruff_benchmark
|
||
# binary crate containing utilities used in the development of Ruff itself
|
||
rm --recursive --verbose ruff/crates/ruff_dev
|
||
# library crate for exposing Ruff as a WebAssembly module. Powers the
|
||
# [Ruff Playground](https://play.ruff.rs/).
|
||
rm --recursive --verbose ruff/crates/ruff_wasm ruff/crates/ty_wasm
|
||
|
||
# Verify we have the correct snapshot hash for typeshed
|
||
typeshed_rev_file='ruff/crates/ty_vendored/vendor/typeshed/source_commit.txt'
|
||
typeshed_rev_in_source="$(cat "${typeshed_rev_file}")"
|
||
if [[ '%{typeshed_rev}' != "${typeshed_rev_in_source}" ]]
|
||
then
|
||
cat 1>&2 <<EOF
|
||
Mismatch between %%{typeshed_rev}:
|
||
%{typeshed_rev}
|
||
and ${typeshed_rev_file}:
|
||
${typeshed_rev_in_source}
|
||
Please update %%{typeshed_rev} in the spec file!
|
||
EOF
|
||
exit 1
|
||
fi
|
||
|
||
|
||
%generate_buildrequires -p
|
||
# For unclear reasons, maturin checks for all crate dependencies when it is
|
||
# invoked as part of %%pyproject_buildrequires – including those corresponding
|
||
# to optional features.
|
||
#
|
||
# Furthermore, if we do not supply -a to %%cargo_generate_buildrequires, then
|
||
# maturin will fail looking for crates like pyo3 (and will still look for
|
||
# optional crate dependencies).
|
||
#
|
||
# Since maturin always checks for dev-dependencies, we need -t so that they are
|
||
# generated even when the “check” bcond is disabled.
|
||
pushd ruff >/dev/null
|
||
%cargo_generate_buildrequires -a -t
|
||
pushd crates/ty >/dev/null
|
||
%cargo_generate_buildrequires -a -t
|
||
popd >/dev/null
|
||
popd >/dev/null
|
||
|
||
|
||
%build -a
|
||
cd ruff
|
||
%{cargo_license_summary}
|
||
%{cargo_license} > LICENSE.dependencies
|
||
|
||
|
||
%install -a
|
||
if [ '%{python3_sitearch}' != '%{python3_sitelib}' ]
|
||
then
|
||
# Maturin is really designed to build compiled Python extensions, but (when
|
||
# the ty executable is not bundled in the Python package) the ty Python
|
||
# library is actually pure-Python, and the python3-ty subpackage can be
|
||
# noarch. We can’t tell maturin to install to the appropriate site-packages
|
||
# directory, but we can fix the installation path manually.
|
||
install --directory %{buildroot}%{python3_sitelib}
|
||
mv %{buildroot}%{python3_sitearch}/ty* %{buildroot}%{python3_sitelib}
|
||
sed --regexp-extended --in-place \
|
||
's@%{python3_sitearch}@%{python3_sitelib}@' %{pyproject_files}
|
||
fi
|
||
|
||
# generate and install shell completions
|
||
ruff/target/rpm/ty generate-shell-completion bash > ty.bash
|
||
ruff/target/rpm/ty generate-shell-completion fish > ty.fish
|
||
ruff/target/rpm/ty generate-shell-completion zsh > _ty
|
||
|
||
install -Dpm 0644 ty.bash -t %{buildroot}/%{bash_completions_dir}
|
||
install -Dpm 0644 ty.fish -t %{buildroot}/%{fish_completions_dir}
|
||
install -Dpm 0644 _ty -t %{buildroot}/%{zsh_completions_dir}
|
||
|
||
|
||
%check -a
|
||
%if %{with check}
|
||
# Ignore false positive snapshot test failures.
|
||
#export INSTA_UPDATE=always
|
||
|
||
# We may need this if rustc diagnostics change from what upstream expects.
|
||
#export TRYBUILD=overwrite
|
||
|
||
# Fails cryptically: requires network, perhaps?
|
||
# error: no matching package named `boxcar` found
|
||
# location searched: crates.io index
|
||
skip="${skip-} --skip compile_fail"
|
||
|
||
# These tests are flaky, e.g.:
|
||
# thread 'python_environment::ty_environment_and_discovered_venv' panicked at
|
||
# /usr/share/cargo/registry/insta-cmd-0.6.0/src/spawn.rs:103:27:
|
||
# called `Result::unwrap()` on an `Err` value: Os { code: 26, kind:
|
||
# ExecutableFileBusy, message: "Text file busy" }
|
||
# This seems to be a testing issue, since the panic comes from insta. It might
|
||
# be fixed by using “cargo nextest” instead of “cargo test,” as upstream does,
|
||
# since nextest has better test isolation. For now, we skip these and move on.
|
||
# Confirmed flaky on ppc64le:
|
||
skip="${skip-} --skip python_environment::ty_environment_and_active_environment"
|
||
# Confirmed flaky on ppc64le:
|
||
skip="${skip-} --skip python_environment::ty_environment_and_discovered_venv"
|
||
# Confirmed flaky on ppc64le and x86_64:
|
||
skip="${skip-} --skip python_environment::ty_environment_is_only_environment"
|
||
# Not confirmed flaky, but the other ty_environment_* ones are, so…
|
||
skip="${skip-} --skip python_environment::ty_environment_is_system_not_virtual"
|
||
|
||
# TODO: This looks innocuous, but exactly which upstream assumption is violated
|
||
# in the build environment, and can we do anything about it?
|
||
#
|
||
# ---- unix::symlink_inside_project stdout ----
|
||
# thread 'unix::symlink_inside_project' (23715) panicked at crates/ty/tests/file_watching.rs:2036:14:
|
||
# Indexed project files contains '/tmp/.tmpxyayv9/project/bar/baz.py' which was not expected.
|
||
skip="${skip-} --skip unix::symlink_inside_project"
|
||
|
||
%ifarch s390x
|
||
# This panics consistently on s390x only; not reported upstream since it
|
||
# couldn’t be reproduced in a git checkout under qemu-user-static emulation.
|
||
skip="${skip-} --skip mdtest__generics_specialize_constrained"
|
||
%endif
|
||
|
||
cd ruff
|
||
# Avoid flaky “text file busy” errors in insta tests
|
||
export RUST_TEST_THREADS=1
|
||
%cargo_test -- -- ${skip-}
|
||
%endif
|
||
|
||
|
||
%files
|
||
%license LICENSE ruff/LICENSE.dependencies LICENSE.bundled/
|
||
%doc CHANGELOG.md
|
||
%doc README.md
|
||
|
||
%{_bindir}/ty
|
||
|
||
%{bash_completions_dir}/ty.bash
|
||
%{fish_completions_dir}/ty.fish
|
||
%{zsh_completions_dir}/_ty
|
||
|
||
|
||
%files -n python3-ty -f %{pyproject_files}
|
||
|
||
|
||
%changelog
|
||
%autochangelog
|