Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed
- Importing a `result.json` no longer fails when a result has an empty `version` or `latest` value.
- Snippet match highlight in the compare view no longer disappears after scrolling: the match is now marked on the scrollbar, and scrolling one editor keeps the other aligned on its corresponding match.
- Dependency scanning no longer crashes when a project is scanned with **Include all file types** enabled.

## [1.39.2] - 2026-05-13
### Fixed
Expand Down
22 changes: 20 additions & 2 deletions src/main/task/scanner/dependency/DependencyTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { ScannerFactory } from '../ScannerFactory';
import fs from 'fs';
import log from 'electron-log';
import i18next from 'i18next';
import { BlackListDependencies } from '../../../workspace/tree/blackList/BlackListDependencies';
import { BlackListDependencies, DependencyFilterRule } from '../../../workspace/tree/blackList/BlackListDependencies';
import { Project } from '../../../workspace/Project';
import { dependencyService } from '../../../services/DependencyService';
import { Scanner } from '../types';
Expand Down Expand Up @@ -34,12 +34,30 @@ export class DependencyTask implements Scanner.IPipelineTask {
return true;
}

/**
* Reads the folder-filter rules used to exclude paths from dependency scanning.
*
* `filter.json` is written during indexing only when project-level file filtering
* is active. When a project is scanned with "Include all file types" enabled the
* file is never created, so there are no rules to apply: an empty list is returned
* (nothing excluded) instead of letting a missing file crash the dependency stage.
*/
private async loadDependencyFilterRules(): Promise<DependencyFilterRule[]> {
const filterPath = `${this.project.metadata.getMyPath()}/filter.json`;
if (!fs.existsSync(filterPath)) {
log.info('[ DependencyTask ]: filter.json not found, skipping dependency filters (all extensions enabled)');
return [];
}
const raw = await fs.promises.readFile(filterPath, 'utf8');
return JSON.parse(raw).filters ?? [];
}
Comment thread
agustingroh marked this conversation as resolved.

private async scanDependencies() {
try {
const allFiles = [];
const rootPath = this.project.metadata.getScanRoot();
const collector = new CollectFilesVisitor(
new BlackListDependencies(`${this.project.metadata.getMyPath()}/filter.json`),
new BlackListDependencies(await this.loadDependencyFilterRules()),
);
this.project.tree.getRootFolder().accept<void>(collector);
collector.files.forEach((f) => {
Expand Down
38 changes: 23 additions & 15 deletions src/main/workspace/tree/blackList/BlackListDependencies.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,33 @@
import * as fs from 'fs';
import { NameFilter, AbstractFilter } from '../../filtering';
import { BlackListAbstract } from './BlackListAbstract';
import Node, { NodeStatus } from '../Node';
import Node from '../Node';

/** Shape of a single filter rule as persisted in the project's `filter.json`. */
export interface DependencyFilterRule {
ftype: string;
scope: string;
condition: string;
value: string;
}

export class BlackListDependencies extends BlackListAbstract {
private filters: Array<AbstractFilter> = [];

public constructor(path: string) {
/**
* Builds the dependency blacklist from filter rules (as persisted in the
* project's `filter.json`). Only NAME/FOLDER rules are applied.
*
* Reading the rules from disk is intentionally left to the caller: this class
* only owns the filtering logic, mirroring the other BlackList* filters which
* keep their rules in memory. An empty list means nothing is excluded — e.g.
* when a project is scanned with "Include all file types" enabled, no
* `filter.json` is generated and the caller passes no rules.
*/
public constructor(rules: Array<DependencyFilterRule> = []) {
super();
this.load(path);
}

private load(path: string) {
const file = fs.readFileSync(path, 'utf8');
const f = JSON.parse(file);
const { filters } = f;

let i: number;
for (i = 0; i < filters.length; i += 1) {
if (filters[i].ftype === 'NAME' && filters[i].scope === 'FOLDER') this.filters.push(new NameFilter(filters[i].condition, filters[i].value, filters[i].scope));
}
rules
.filter((rule) => rule.ftype === 'NAME' && rule.scope === 'FOLDER')
.forEach((rule) => this.filters.push(new NameFilter(rule.condition, rule.value, rule.scope)));
}

public evaluate(node: Node): boolean {
Expand Down
Loading