• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

pantsbuild / pants / 25443604553

06 May 2026 03:05PM UTC coverage: 92.879% (-0.04%) from 92.915%
25443604553

push

github

web-flow
[pants_ng] Scaffolding for a pants_ng mode. (#23319)

In this mode the command line is parsed as an
NG invocation, and dispatched appropriately.

Of course at the moment there are no
implementations to dispatch to. That will follow.

This does expose a new option, `pants_ng` to users. 
There is a big warning not to set it, but we're not trying
to hide that we're working on a new thing, so I am
comfortable with this.

25 of 76 new or added lines in 9 files covered. (32.89%)

1294 existing lines in 76 files now uncovered.

92234 of 99306 relevant lines covered (92.88%)

4.05 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.87
/src/python/pants/backend/typescript/goals/check.py
1
# Copyright 2025 Pants project contributors (see CONTRIBUTORS.md).
2
# Licensed under the Apache License, Version 2.0 (see LICENSE).
3

UNCOV
4
from __future__ import annotations
1✔
5

UNCOV
6
import logging
1✔
UNCOV
7
import os
1✔
UNCOV
8
from dataclasses import dataclass, replace
1✔
UNCOV
9
from hashlib import sha256
1✔
UNCOV
10
from pathlib import Path
1✔
UNCOV
11
from typing import TYPE_CHECKING
1✔
12

UNCOV
13
from pants.backend.javascript.nodejs_project import AllNodeJSProjects, find_node_js_projects
1✔
UNCOV
14
from pants.backend.javascript.package_json import (
1✔
15
    AllPackageJson,
16
    OwningNodePackageRequest,
17
    PackageJson,
18
    all_package_json,
19
    find_owning_package,
20
)
UNCOV
21
from pants.backend.javascript.resolve import RequestNodeResolve, resolve_for_package
1✔
UNCOV
22
from pants.backend.javascript.subsystems.nodejs_tool import NodeJSToolRequest, prepare_tool_process
1✔
UNCOV
23
from pants.backend.javascript.target_types import JSRuntimeSourceField
1✔
UNCOV
24
from pants.backend.typescript.subsystem import TypeScriptSubsystem
1✔
UNCOV
25
from pants.backend.typescript.target_types import TypeScriptSourceField, TypeScriptTestSourceField
1✔
UNCOV
26
from pants.backend.typescript.tsconfig import AllTSConfigs, TSConfig, construct_effective_ts_configs
1✔
UNCOV
27
from pants.base.build_root import BuildRoot
1✔
UNCOV
28
from pants.build_graph.address import Address
1✔
UNCOV
29
from pants.core.goals.check import CheckRequest, CheckResult, CheckResults, CheckSubsystem
1✔
UNCOV
30
from pants.core.target_types import FileSourceField
1✔
UNCOV
31
from pants.core.util_rules.system_binaries import CpBinary, FindBinary, MkdirBinary, TouchBinary
1✔
UNCOV
32
from pants.engine.fs import (
1✔
33
    EMPTY_DIGEST,
34
    CreateDigest,
35
    Digest,
36
    FileContent,
37
    GlobMatchErrorBehavior,
38
    PathGlobs,
39
)
UNCOV
40
from pants.engine.internals.graph import find_all_targets, hydrate_sources, transitive_targets
1✔
UNCOV
41
from pants.engine.internals.native_engine import MergeDigests
1✔
UNCOV
42
from pants.engine.internals.selectors import concurrently
1✔
UNCOV
43
from pants.engine.intrinsics import (
1✔
44
    create_digest,
45
    execute_process,
46
    merge_digests,
47
    path_globs_to_digest,
48
)
UNCOV
49
from pants.engine.process import Process
1✔
UNCOV
50
from pants.engine.rules import collect_rules, implicitly, rule
1✔
UNCOV
51
from pants.engine.target import (
1✔
52
    AllTargets,
53
    FieldSet,
54
    HydrateSourcesRequest,
55
    Target,
56
    TransitiveTargetsRequest,
57
)
UNCOV
58
from pants.engine.unions import UnionRule
1✔
UNCOV
59
from pants.option.global_options import GlobalOptions
1✔
UNCOV
60
from pants.util.frozendict import FrozenDict
1✔
UNCOV
61
from pants.util.logging import LogLevel
1✔
UNCOV
62
from pants.util.ordered_set import FrozenOrderedSet, OrderedSet
1✔
63

64
if TYPE_CHECKING:
65
    from pants.backend.javascript.nodejs_project import NodeJSProject
66

UNCOV
67
logger = logging.getLogger(__name__)
1✔
68

69

UNCOV
70
@dataclass(frozen=True)
1✔
UNCOV
71
class CreateTscWrapperScriptRequest:
1✔
UNCOV
72
    project: NodeJSProject
1✔
UNCOV
73
    package_output_dirs: tuple[str, ...]
1✔
UNCOV
74
    build_root: BuildRoot
1✔
UNCOV
75
    named_cache_sandbox_mount_dir: str
1✔
UNCOV
76
    tsc_wrapper_filename: str
1✔
77

78

UNCOV
79
@dataclass(frozen=True)
1✔
UNCOV
80
class TypeScriptCheckFieldSet(FieldSet):
1✔
UNCOV
81
    required_fields = (JSRuntimeSourceField,)
1✔
82

UNCOV
83
    sources: JSRuntimeSourceField
1✔
84

85

UNCOV
86
class TypeScriptCheckRequest(CheckRequest):
1✔
UNCOV
87
    field_set_type = TypeScriptCheckFieldSet
1✔
UNCOV
88
    tool_name = TypeScriptSubsystem.options_scope
1✔
89

90

UNCOV
91
def _build_workspace_tsconfig_map(
1✔
92
    workspaces: FrozenOrderedSet[PackageJson], all_ts_configs: list[TSConfig]
93
) -> dict[str, TSConfig]:
UNCOV
94
    workspace_dir_map = {os.path.normpath(pkg.root_dir): pkg for pkg in workspaces}
1✔
UNCOV
95
    workspace_dir_to_tsconfig: dict[str, TSConfig] = {}
1✔
96

97
    # Only consider tsconfig.json files (exclude tsconfig.build.json, tsconfig.test.json, etc.)
98
    # since tsc only reads tsconfig.json by default and we don't support the `--project` flag currently
99
    # Additionally, TSConfig class only supports tsconfig.json.
UNCOV
100
    tsconfig_json_files = [
1✔
101
        cfg for cfg in all_ts_configs if os.path.basename(cfg.path) == "tsconfig.json"
102
    ]
103

UNCOV
104
    for ts_config in tsconfig_json_files:
1✔
UNCOV
105
        config_dir = os.path.normpath(os.path.dirname(ts_config.path))
1✔
106

UNCOV
107
        if config_dir in workspace_dir_map:
1✔
UNCOV
108
            workspace_dir_to_tsconfig[config_dir] = ts_config
1✔
109

UNCOV
110
    return workspace_dir_to_tsconfig
1✔
111

112

UNCOV
113
def _collect_package_output_dirs(
1✔
114
    project: NodeJSProject, project_ts_configs: list[TSConfig], project_root_path: Path
115
) -> tuple[str, ...]:
UNCOV
116
    workspace_dir_to_tsconfig = _build_workspace_tsconfig_map(
1✔
117
        project.workspaces, project_ts_configs
118
    )
119

UNCOV
120
    package_output_dirs: OrderedSet[str] = OrderedSet()
1✔
UNCOV
121
    for workspace_pkg in project.workspaces:
1✔
UNCOV
122
        workspace_pkg_path = Path(workspace_pkg.root_dir)
1✔
123

UNCOV
124
        if workspace_pkg_path == project_root_path:
1✔
UNCOV
125
            pkg_prefix = ""
1✔
126
        else:
UNCOV
127
            relative_path = workspace_pkg_path.relative_to(project_root_path)
1✔
UNCOV
128
            pkg_prefix = f"{relative_path.as_posix()}/"
1✔
129

UNCOV
130
        pkg_tsconfig = workspace_dir_to_tsconfig.get(os.path.normpath(workspace_pkg.root_dir))
1✔
131

UNCOV
132
        if pkg_tsconfig and pkg_tsconfig.out_dir:
1✔
UNCOV
133
            resolved_out_dir = f"{pkg_prefix}{pkg_tsconfig.out_dir.lstrip('./')}"
1✔
UNCOV
134
            package_output_dirs.add(resolved_out_dir)
1✔
135

UNCOV
136
    return tuple(package_output_dirs)
1✔
137

138

UNCOV
139
def _collect_project_configs(
1✔
140
    project: NodeJSProject, all_package_jsons: AllPackageJson, all_ts_configs: AllTSConfigs
141
) -> tuple[list, list[TSConfig]]:
UNCOV
142
    project_package_jsons = [
1✔
143
        pkg for pkg in all_package_jsons if pkg.root_dir.startswith(project.root_dir)
144
    ]
UNCOV
145
    project_ts_configs = [
1✔
146
        config for config in all_ts_configs if config.path.startswith(project.root_dir)
147
    ]
UNCOV
148
    return project_package_jsons, project_ts_configs
1✔
149

150

UNCOV
151
async def _collect_config_files_for_project(
1✔
152
    project: NodeJSProject,
153
    targets: list[Target],
154
    project_package_jsons: list,
155
    project_ts_configs: list[TSConfig],
156
) -> list[str]:
UNCOV
157
    config_files = []
1✔
158

UNCOV
159
    for pkg_json in project_package_jsons:
1✔
UNCOV
160
        config_files.append(pkg_json.file)
1✔
161

UNCOV
162
    for ts_config in project_ts_configs:
1✔
UNCOV
163
        config_files.append(ts_config.path)
1✔
164

165
    # Add file() targets that are dependencies of JS/TS targets
166
    # Note: Package manager config files
167
    # (.npmrc, .pnpmrc, pnpm-workspace.yaml) should be dependencies of package_json targets
168
    # since they affect package installation, not TypeScript compilation directly.
UNCOV
169
    target_addresses = [target.address for target in targets]
1✔
UNCOV
170
    transitive_targets_result = await transitive_targets(
1✔
171
        TransitiveTargetsRequest(target_addresses), **implicitly()
172
    )
173

UNCOV
174
    for target in transitive_targets_result.closure:
1✔
UNCOV
175
        if target.has_field(FileSourceField):
1✔
UNCOV
176
            file_path = target[FileSourceField].file_path
1✔
UNCOV
177
            if file_path.startswith(project.root_dir):
1✔
UNCOV
178
                config_files.append(file_path)
1✔
179

UNCOV
180
    return config_files
1✔
181

182

UNCOV
183
@rule
1✔
UNCOV
184
async def create_tsc_wrapper_script(
1✔
185
    request: CreateTscWrapperScriptRequest,
186
    cp_binary: CpBinary,
187
    mkdir_binary: MkdirBinary,
188
    find_binary: FindBinary,
189
    touch_binary: TouchBinary,
190
) -> Digest:
UNCOV
191
    project = request.project
1✔
UNCOV
192
    package_output_dirs = request.package_output_dirs
1✔
UNCOV
193
    build_root = request.build_root
1✔
UNCOV
194
    named_cache_sandbox_mount_dir = request.named_cache_sandbox_mount_dir
1✔
UNCOV
195
    tsc_wrapper_filename = request.tsc_wrapper_filename
1✔
196

UNCOV
197
    project_abs_path = os.path.join(build_root.path, project.root_dir)
1✔
UNCOV
198
    cache_key = sha256(project_abs_path.encode()).hexdigest()
1✔
199

UNCOV
200
    project_depth = len([p for p in project.root_dir.strip("/").split("/") if p])
1✔
UNCOV
201
    cache_relative_path = (
1✔
202
        "../" * project_depth + named_cache_sandbox_mount_dir
203
        if project_depth > 0
204
        else named_cache_sandbox_mount_dir
205
    )
UNCOV
206
    project_cache_subdir = f"{cache_relative_path}/{cache_key}"
1✔
207

UNCOV
208
    package_dirs = []
1✔
UNCOV
209
    for workspace_pkg in project.workspaces:
1✔
UNCOV
210
        if workspace_pkg.root_dir != project.root_dir:
1✔
UNCOV
211
            package_relative = workspace_pkg.root_dir.removeprefix(f"{project.root_dir}/")
1✔
UNCOV
212
            package_dirs.append(package_relative)
1✔
213
        else:
UNCOV
214
            package_dirs.append(".")
1✔
UNCOV
215
    package_dirs_str = " ".join(f'"{d}"' for d in package_dirs)
1✔
UNCOV
216
    output_dirs_str = " ".join(f'"{d}"' for d in package_output_dirs)
1✔
217

UNCOV
218
    script_content = f"""#!/bin/sh
1✔
219
# TypeScript incremental compilation cache wrapper
220

221
# All source files in sandbox have mtime as at sandbox creation (e.g. when the process started).
222
# Without any special handling, tsc will do a fast immediate rebuild (without checking tsbuildinfo metadata).
223
# (tsc outputs: "Project 'tsconfig.json' is out of date because output 'tsconfig.tsbuildinfo' is older than input 'tsconfig.json'")
224
# What we want: tsconfig (oldest), tsbuildinfo (newer), source files (newest).
225
# See also https://github.com/microsoft/TypeScript/issues/54563
226

227
set -e
228

229
CP_BIN="{cp_binary.path}"
230
MKDIR_BIN="{mkdir_binary.path}"
231
FIND_BIN="{find_binary.path}"
232
TOUCH_BIN="{touch_binary.path}"
233

234
PROJECT_CACHE_SUBDIR="{project_cache_subdir}"
235

236
# Ensure cache directory exists (it won't on first run)
237
"$MKDIR_BIN" -p "$PROJECT_CACHE_SUBDIR" > /dev/null 2>&1
238

239
# Copy cached files to working directory
240
"$CP_BIN" -a "$PROJECT_CACHE_SUBDIR/." . > /dev/null 2>&1
241

242
# Make tsconfig files oldest
243
# This could be improved by passing a list of tsconfig files, but that might be best done if/when we have a Target for tsconfig files.
244
"$FIND_BIN" . -type f -name "tsconfig*.json" -exec "$TOUCH_BIN" -t 202001010000 {{}} +
245

246
# Run tsc
247
"$@"
248

249
# Update cache
250
# Copy .tsbuildinfo files located at package root to cache
251
for package_dir in {package_dirs_str}; do
252
    for tsbuildinfo_file in "$package_dir"/*.tsbuildinfo; do
253
        if [ -f "$tsbuildinfo_file" ]; then
254
            "$MKDIR_BIN" -p "$PROJECT_CACHE_SUBDIR/$package_dir"
255
            "$CP_BIN" "$tsbuildinfo_file" "$PROJECT_CACHE_SUBDIR/$package_dir/"
256
        fi
257
    done
258
done
259

260
# Copy output directories to cache
261
# (the output files are needed because tsc checks them against tsbuildinfo hashes when determining if a rebuild is required)
262
for output_dir in {output_dirs_str}; do
263
    if [ -d "$output_dir" ]; then
264
        output_parent="$(dirname "$output_dir")"
265
        "$MKDIR_BIN" -p "$PROJECT_CACHE_SUBDIR/$output_parent"
266
        "$CP_BIN" -r "$output_dir" "$PROJECT_CACHE_SUBDIR/$output_parent/"
267
    fi
268
done
269
"""
270

UNCOV
271
    script_digest = await create_digest(
1✔
272
        CreateDigest(
273
            [
274
                FileContent(
275
                    f"{project.root_dir}/{tsc_wrapper_filename}",
276
                    script_content.encode(),
277
                    is_executable=True,
278
                )
279
            ]
280
        ),
281
        **implicitly(),
282
    )
283

UNCOV
284
    return script_digest
1✔
285

286

UNCOV
287
async def _collect_project_targets(
1✔
288
    project: NodeJSProject,
289
    all_targets: AllTargets,
290
    all_projects: AllNodeJSProjects,
291
    project_ts_configs: list[TSConfig],
292
) -> list[Target]:
UNCOV
293
    has_check_js = any(
1✔
294
        ts_config.allow_js and ts_config.check_js for ts_config in project_ts_configs
295
    )
296

UNCOV
297
    if has_check_js:
1✔
UNCOV
298
        targets = [target for target in all_targets if target.has_field(JSRuntimeSourceField)]
1✔
299
    else:
UNCOV
300
        targets = [
1✔
301
            target
302
            for target in all_targets
303
            if (
304
                target.has_field(TypeScriptSourceField)
305
                or target.has_field(TypeScriptTestSourceField)
306
            )
307
        ]
308

UNCOV
309
    target_owning_packages = await concurrently(
1✔
310
        find_owning_package(OwningNodePackageRequest(target.address), **implicitly())
311
        for target in targets
312
    )
313

UNCOV
314
    project_targets = []
1✔
UNCOV
315
    for target, owning_package in zip(targets, target_owning_packages):
1✔
UNCOV
316
        if owning_package.target:
1✔
UNCOV
317
            package_directory = owning_package.target.address.spec_path
1✔
UNCOV
318
            target_project = all_projects.project_for_directory(package_directory)
1✔
UNCOV
319
            if target_project == project:
1✔
UNCOV
320
                project_targets.append(target)
1✔
321

UNCOV
322
    return project_targets
1✔
323

324

UNCOV
325
async def _hydrate_project_sources(
1✔
326
    project_targets: list[Target],
327
) -> Digest:
UNCOV
328
    workspace_target_sources = await concurrently(
1✔
329
        hydrate_sources(
330
            HydrateSourcesRequest(target[JSRuntimeSourceField]),
331
            **implicitly(),
332
        )
333
        for target in project_targets
334
    )
335

UNCOV
336
    return await merge_digests(
1✔
337
        MergeDigests([sources.snapshot.digest for sources in workspace_target_sources])
338
    )
339

340

UNCOV
341
async def _prepare_compilation_input(
1✔
342
    project: NodeJSProject,
343
    project_targets: list[Target],
344
    project_package_jsons: list,
345
    project_ts_configs: list[TSConfig],
346
    all_workspace_sources: Digest,
347
) -> Digest:
UNCOV
348
    config_files = await _collect_config_files_for_project(
1✔
349
        project, project_targets, project_package_jsons, project_ts_configs
350
    )
UNCOV
351
    for ts_config in project_ts_configs:
1✔
UNCOV
352
        ts_config.validate_outdir()
1✔
353

UNCOV
354
    config_digest = (
1✔
355
        await path_globs_to_digest(
356
            PathGlobs(config_files, glob_match_error_behavior=GlobMatchErrorBehavior.ignore),
357
            **implicitly(),
358
        )
359
        if config_files
360
        else EMPTY_DIGEST
361
    )
362

UNCOV
363
    return await merge_digests(MergeDigests([all_workspace_sources, config_digest]))
1✔
364

365

UNCOV
366
async def _prepare_tsc_build_process(
1✔
367
    project: NodeJSProject,
368
    subsystem: TypeScriptSubsystem,
369
    input_digest: Digest,
370
    package_output_dirs: tuple[str, ...],
371
    project_targets: list[Target],
372
    build_root: BuildRoot,
373
) -> Process:
UNCOV
374
    tsc_args = ("--build", *subsystem.extra_build_args)
1✔
UNCOV
375
    tsc_wrapper_filename = "__tsc_wrapper.sh"
1✔
UNCOV
376
    named_cache_local_dir = "typescript_cache"
1✔
UNCOV
377
    named_cache_sandbox_mount_dir = "._tsc_cache"
1✔
378

UNCOV
379
    project_resolve = await resolve_for_package(
1✔
380
        RequestNodeResolve(Address(project.root_dir)), **implicitly()
381
    )
382

UNCOV
383
    script_digest = await create_tsc_wrapper_script(
1✔
384
        CreateTscWrapperScriptRequest(
385
            project=project,
386
            package_output_dirs=package_output_dirs,
387
            build_root=build_root,
388
            named_cache_sandbox_mount_dir=named_cache_sandbox_mount_dir,
389
            tsc_wrapper_filename=tsc_wrapper_filename,
390
        ),
391
        **implicitly(),
392
    )
393

UNCOV
394
    tool_input = await merge_digests(MergeDigests([input_digest, script_digest]))
1✔
395

UNCOV
396
    tool_request = subsystem.request(
1✔
397
        args=tsc_args,
398
        input_digest=tool_input,
399
        description=f"Type-check TypeScript project {project.root_dir} ({len(project_targets)} targets)",
400
        level=LogLevel.DEBUG,
401
        project_caches=FrozenDict({named_cache_local_dir: named_cache_sandbox_mount_dir}),
402
    )
403

404
    # Uses the project's resolve as TypeScript execution requires project deps.
UNCOV
405
    tool_request_with_resolve: NodeJSToolRequest = replace(
1✔
406
        tool_request, resolve=project_resolve.resolve_name
407
    )
408

UNCOV
409
    process = await prepare_tool_process(tool_request_with_resolve, **implicitly())
1✔
410

UNCOV
411
    process_with_wrapper = replace(
1✔
412
        process,
413
        argv=(f"./{tsc_wrapper_filename}",) + process.argv,
414
        working_directory=project.root_dir,
415
        output_directories=package_output_dirs,
416
    )
417

UNCOV
418
    return process_with_wrapper
1✔
419

420

UNCOV
421
async def _typecheck_single_project(
1✔
422
    project: NodeJSProject,
423
    subsystem: TypeScriptSubsystem,
424
    check_subsystem: CheckSubsystem,
425
    global_options: GlobalOptions,
426
    all_targets: AllTargets,
427
    all_projects: AllNodeJSProjects,
428
    all_package_jsons: AllPackageJson,
429
    all_ts_configs: AllTSConfigs,
430
    build_root: BuildRoot,
431
) -> CheckResult:
UNCOV
432
    project_package_jsons, project_ts_configs = _collect_project_configs(
1✔
433
        project, all_package_jsons, all_ts_configs
434
    )
435

UNCOV
436
    project_targets = await _collect_project_targets(
1✔
437
        project, all_targets, all_projects, project_ts_configs
438
    )
439

UNCOV
440
    if not project_targets:
1✔
441
        return CheckResult(
×
442
            exit_code=0,
443
            stdout="",
444
            stderr="",
445
            partition_description=f"TypeScript check on {project.root_dir} (no targets)",
446
        )
447

UNCOV
448
    all_workspace_sources = await _hydrate_project_sources(project_targets)
1✔
UNCOV
449
    input_digest = await _prepare_compilation_input(
1✔
450
        project,
451
        project_targets,
452
        project_package_jsons,
453
        project_ts_configs,
454
        all_workspace_sources,
455
    )
UNCOV
456
    package_output_dirs = _collect_package_output_dirs(
1✔
457
        project, project_ts_configs, Path(project.root_dir)
458
    )
459

UNCOV
460
    process = await _prepare_tsc_build_process(
1✔
461
        project,
462
        subsystem,
463
        input_digest,
464
        package_output_dirs,
465
        project_targets,
466
        build_root,
467
    )
468

UNCOV
469
    process = replace(process, cache_scope=check_subsystem.default_process_cache_scope)
1✔
470

UNCOV
471
    result = await execute_process(process, **implicitly())
1✔
472

UNCOV
473
    return CheckResult.from_fallible_process_result(
1✔
474
        result,
475
        partition_description=f"TypeScript check on {project.root_dir} ({len(project_targets)} targets)",
476
        output_simplifier=global_options.output_simplifier(),
477
    )
478

479

UNCOV
480
@rule(desc="Check TypeScript compilation")
1✔
UNCOV
481
async def typecheck_typescript(
1✔
482
    request: TypeScriptCheckRequest,
483
    subsystem: TypeScriptSubsystem,
484
    check_subsystem: CheckSubsystem,
485
    global_options: GlobalOptions,
486
    build_root: BuildRoot,
487
) -> CheckResults:
UNCOV
488
    if subsystem.skip:
1✔
489
        return CheckResults([], checker_name=request.tool_name, output_per_partition=False)
×
490

UNCOV
491
    field_sets = request.field_sets
1✔
UNCOV
492
    (
1✔
493
        all_projects,
494
        all_targets,
495
        all_package_jsons,
496
        all_ts_configs,
497
        owning_packages,
498
    ) = await concurrently(
499
        find_node_js_projects(**implicitly()),
500
        find_all_targets(),
501
        all_package_json(),
502
        construct_effective_ts_configs(),
503
        concurrently(
504
            find_owning_package(OwningNodePackageRequest(field_set.address), **implicitly())
505
            for field_set in field_sets
506
        ),
507
    )
508

UNCOV
509
    projects: OrderedSet[NodeJSProject] = OrderedSet()
1✔
UNCOV
510
    for owning_package in owning_packages:
1✔
UNCOV
511
        if owning_package.target:
1✔
UNCOV
512
            package_directory = owning_package.target.address.spec_path
1✔
UNCOV
513
            owning_project = all_projects.project_for_directory(package_directory)
1✔
UNCOV
514
            if owning_project:
1✔
UNCOV
515
                projects.add(owning_project)
1✔
516

UNCOV
517
    project_results = await concurrently(
1✔
518
        _typecheck_single_project(
519
            project,
520
            subsystem,
521
            check_subsystem,
522
            global_options,
523
            all_targets,
524
            all_projects,
525
            all_package_jsons,
526
            all_ts_configs,
527
            build_root,
528
        )
529
        for project in projects
530
    )
531

UNCOV
532
    return CheckResults(project_results, checker_name=request.tool_name, output_per_partition=False)
1✔
533

534

UNCOV
535
def rules():
1✔
UNCOV
536
    return [
1✔
537
        *collect_rules(),
538
        UnionRule(CheckRequest, TypeScriptCheckRequest),
539
    ]
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc