Skip to content

Commit 97bf2b5

Browse files
committed
Introduce a enum of NORMAL_DEVELOPMENT | BUILD
1 parent 497e81a commit 97bf2b5

File tree

1 file changed

+29
-14
lines changed
  • onlinejudge_verify/languages

1 file changed

+29
-14
lines changed

onlinejudge_verify/languages/rust.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
import abc
2+
import enum
23
import functools
34
import itertools
45
import json
56
import pathlib
67
import shutil
78
import subprocess
9+
from collections import defaultdict
10+
from enum import Enum
811
from logging import getLogger
912
from subprocess import PIPE
1013
from typing import *
@@ -69,23 +72,33 @@ def _list_dependencies_by_crate(path: pathlib.Path, *, basedir: pathlib.Path, ca
6972

7073
packages_by_id = {p['id']: p for p in metadata['packages']}
7174

75+
class DependencyNamespace(Enum):
76+
NORMAL_DEVELOPMENT = enum.auto()
77+
BUILD = enum.auto()
78+
79+
@classmethod
80+
def from_dep_kind(cls, kind: str):
81+
if kind == 'build':
82+
return cls.BUILD
83+
return cls.NORMAL_DEVELOPMENT
84+
7285
# Collect the `(|dev-|build-)dependencies` into a <is a `build-dependency`> → (<"extern crate name"> → <package>) dictionary.
73-
dependencies: Dict[bool, Dict[str, Dict[str, Any]]] = {False: {}, True: {}}
86+
dependencies: DefaultDict[DependencyNamespace, Dict[str, Dict[str, Any]]] = defaultdict(dict)
7487
for dep in next(n['deps'] for n in metadata['resolve']['nodes'] if n['id'] == main_package['id']):
75-
if any(k['kind'] == ['build'] for k in dep['dep_kinds']):
76-
dependencies[True][dep['name']] = packages_by_id[dep['pkg']]
7788
if _need_dev_deps(main_target) or any(k['kind'] is None for k in dep['dep_kinds']):
78-
dependencies[False][dep['name']] = packages_by_id[dep['pkg']]
89+
dependencies[DependencyNamespace.NORMAL_DEVELOPMENT][dep['name']] = packages_by_id[dep['pkg']]
90+
if any(k['kind'] == ['build'] for k in dep['dep_kinds']):
91+
dependencies[DependencyNamespace.BUILD][dep['name']] = packages_by_id[dep['pkg']]
7992

8093
# Decides whether to include `main_package` itself.
8194
# Note that cargo-udeps does not detect it if it is unused.
8295
# https://github.com/est31/cargo-udeps/pull/35
8396
depends_on_main_package_itself = not _is_lib_or_proc_macro(main_target) and any(map(_is_lib_or_proc_macro, main_package['targets']))
8497

8598
# If `cargo_udeps_toolchain` is present, collects packages that are "unused" by `target`.
86-
unused_packages: Dict[bool, Set[str]] = {False: set(), True: set()}
99+
unused_packages = defaultdict(set)
87100
if cargo_udeps_toolchain is not None:
88-
explicit_names_in_toml = {(d['kind'] == 'build', d['rename']) for d in main_package['dependencies'] if d['rename']}
101+
explicit_names_in_toml = {(DependencyNamespace.from_dep_kind(d['kind']), d['rename']) for d in main_package['dependencies'] if d['rename']}
89102
if not shutil.which('cargo-udeps'):
90103
raise RuntimeError('`cargo-udeps` not in $PATH')
91104
unused_deps = json.loads(subprocess.run(
@@ -96,23 +109,25 @@ def _list_dependencies_by_crate(path: pathlib.Path, *, basedir: pathlib.Path, ca
96109
).stdout.decode())['unused_deps'].values()
97110
unused_dep = next((u for u in unused_deps if u['manifest_path'] == main_package['manifest_path']), None)
98111
if unused_dep:
99-
for is_build, name_in_toml in [*[(False, n) for n in [*unused_dep['normal'], *unused_dep['development']]], *[(True, n) for n in unused_dep['build']]]:
100-
if (is_build, name_in_toml) in explicit_names_in_toml:
112+
names_in_toml = [(DependencyNamespace.NORMAL_DEVELOPMENT, name_in_toml) for name_in_toml in [*unused_dep['normal'], *unused_dep['development']]]
113+
names_in_toml.extend((DependencyNamespace.BUILD, name_in_toml) for name_in_toml in unused_dep['build'])
114+
for dependency_namespace, name_in_toml in names_in_toml:
115+
if (dependency_namespace, name_in_toml) in explicit_names_in_toml:
101116
# If the `name_in_toml` is explicitly renamed one, it equals to the `extern_crate_name`.
102-
unused_packages[is_build].add(dependencies[is_build][name_in_toml]['id'])
117+
unused_packages[dependency_namespace].add(dependencies[dependency_namespace][name_in_toml]['id'])
103118
else:
104119
# Otherwise, it equals to the `package.name`.
105-
unused_packages[is_build].add(next(p['id'] for p in dependencies[is_build].values() if p['name'] == name_in_toml))
120+
unused_packages[dependency_namespace].add(next(p['id'] for p in dependencies[dependency_namespace].values() if p['name'] == name_in_toml))
106121

107122
# Finally, adds source files related to the depended crates except:
108123
#
109124
# - those detected by cargo-udeps
110125
# - those come from Crates.io or Git repositories (e.g. `proconio`, other people's libraries including `ac-library-rs`)
111126
ret = common_result
112-
depended_packages = [(False, main_package)] if depends_on_main_package_itself else []
113-
depended_packages.extend((is_build, package) for is_build, dependencies in dependencies.items() for package in dependencies.values())
114-
for is_build, depended_package in depended_packages:
115-
if depended_package['id'] in unused_packages[is_build] or depended_package['source']:
127+
depended_packages = [(DependencyNamespace.NORMAL_DEVELOPMENT, main_package)] if depends_on_main_package_itself else []
128+
depended_packages.extend((dependency_namespace, package) for dependency_namespace, dependencies in dependencies.items() for package in dependencies.values())
129+
for dependency_namespace, depended_package in depended_packages:
130+
if depended_package['id'] in unused_packages[dependency_namespace] or depended_package['source']:
116131
continue
117132
depended_target = next(filter(_is_lib_or_proc_macro, depended_package['targets']), None)
118133
if depended_target:

0 commit comments

Comments
 (0)