update electron to v43
All checks were successful
Android Build / publish (push) Successful in 55s
Linux Build / publish (push) Successful in 1m6s

This commit is contained in:
olcxja 2026-07-09 22:38:33 +02:00
commit fb6c8b6ee9
5385 changed files with 513060 additions and 123058 deletions

View file

@ -2,7 +2,8 @@ dir-compare
==========
Node JS directory compare
[![Build Status](https://api.travis-ci.org/gliviu/dir-compare.svg?branch=master)](https://travis-ci.org/gliviu/dir-compare)
**Starting with v3.0.0 the CLI utility moved to [dir-compare-cli](https://www.npmjs.com/package/dir-compare-cli).**
[![Build status](https://ci.appveyor.com/api/projects/status/fpnqkr2gfg7pwkxk/branch/master?svg=true)](https://ci.appveyor.com/project/gliviu/dir-compare)
[![codecov.io](http://codecov.io/github/gliviu/dir-compare/coverage.svg?branch=master)](http://codecov.io/github/gliviu/dir-compare?branch=master)
@ -11,23 +12,22 @@ Node JS directory compare
* [Use](#use)
* [Api](#api)
* [Glob patterns](#glob-patterns)
* [Custom file content comparators](#custom-file-content-comparators)
+ [Ignore line endings and white spaces](#ignore-line-endings-and-white-spaces)
* [Custom name comparators](#custom-name-comparators)
* [Custom result builder](#custom-result-builder)
* [Symbolic links](#symbolic-links)
- [Command line](#command-line)
* [Handling permission denied errors](#handling-permission-denied-errors)
- [Extension points](#extension-points)
* [File content comparators](#file-content-comparators)
+ [Ignore line endings and white spaces](#ignore-line-endings-and-white-spaces)
* [Glob filter](#glob-filter)
+ [Implement .gitignore filter](#implement-gitignore-filter)
* [Name comparators](#name-comparators)
* [Result builder](#result-builder)
- [UI tools](#ui-tools)
- [Changelog](#changelog)
# Installation
```shell
$ npm install dir-compare
```bash
npm install dir-compare
```
or
```shell
$ npm install -g dir-compare
```
for command line utility.
# Library
@ -50,15 +50,14 @@ dircompare.compare(path1, path2, options)
.then(res => print(res))
.catch(error => console.error(error));
function print(result) {
console.log('Directories are %s', result.same ? 'identical' : 'different')
console.log('Statistics - equal entries: %s, distinct entries: %s, left only entries: %s, right only entries: %s, differences: %s',
result.equal, result.distinct, result.left, result.right, result.differences)
result.diffSet.forEach(dif => console.log('Difference - name1: %s, type1: %s, name2: %s, type2: %s, state: %s',
dif.name1, dif.type1, dif.name2, dif.type2, dif.state))
result.diffSet.forEach(dif => console.log('Difference - path: %s, name1: %s, type1: %s, name2: %s, type2: %s, state: %s',
dif.relativePath, dif.name1, dif.type1, dif.name2, dif.type2, dif.state))
}
```
@ -79,78 +78,25 @@ compare(path1, path2, options)
## Api
Below is a quick recap of the api. For more details check the [reference documentation](https://gliviu.github.io/dc-api/).
```typescript
compare(path1: string, path2: string, options?: Options): Promise<Result>
compareSync(path1: string, path2: string, options?: Options): Result
```
More details can be found in the reference documentation:
* [compare](https://gliviu.github.io/dc-api/functions/compare.html)
* [compareSync](https://gliviu.github.io/dc-api/functions/compareSync.html)
* [Options](https://gliviu.github.io/dc-api/interfaces/Options.html)
* [Result](https://gliviu.github.io/dc-api/interfaces/Result.html)
```Options```
* **compareSize**: true/false - Compares files by size. Defaults to 'false'.
* **compareContent**: true/false - Compares files by content. Defaults to 'false'.
* **compareFileSync**, **compareFileAsync**: Callbacks for file comparison. See [Custom file content comparators](#custom-file-content-comparators).
* **compareDate**: true/false - Compares files by date of modification (stat.mtime). Defaults to 'false'.
* **compareNameHandler**: Callback for name comparison. See [Custom name comparators](#custom-name-comparators).
* **dateTolerance**: milliseconds - Two files are considered to have the same date if the difference between their modification dates fits within date tolerance. Defaults to 1000 ms.
* **compareSymlink**: true/false - Compares entries by symlink. Defaults to 'false'.
* **skipSymlinks**: true/false - Ignore symbolic links. Defaults to 'false'.
* **skipSubdirs**: true/false - Skips sub directories. Defaults to 'false'.
* **ignoreCase**: true/false - Ignores case when comparing names. Defaults to 'false'.
* **noDiffSet**: true/false - Toggles presence of diffSet in output. If true, only statistics are provided. Use this when comparing large number of files to avoid out of memory situations. Defaults to 'false'.
* **includeFilter**: File name filter. Comma separated [minimatch](https://www.npmjs.com/package/minimatch) patterns. See [Glob patterns](#glob-patterns) below.
* **excludeFilter**: File/directory name exclude filter. Comma separated [minimatch](https://www.npmjs.com/package/minimatch) patterns. See [Glob patterns](#glob-patterns) below.
* **resultBuilder**: Callback for constructing result. Called for each compared entry pair. Updates `statistics` and `diffSet`. More details in [Custom result builder](#custom-result-builder).
```Result```
* **same**: true if directories are identical
* **distinct**: number of distinct entries
* **equal**: number of equal entries
* **left**: number of entries only in path1
* **right**: number of entries only in path2
* **differences**: total number of differences (distinct+left+right)
* **total**: total number of entries (differences+equal)
* **distinctFiles**: number of distinct files
* **equalFiles**: number of equal files
* **leftFiles**: number of files only in path1
* **rightFiles**: number of files only in path2
* **differencesFiles**: total number of different files (distinctFiles+leftFiles+rightFiles)
* **totalFiles**: total number of files (differencesFiles+equalFiles)
* **distinctDirs**: number of distinct directories
* **equalDirs**: number of equal directories
* **leftDirs**: number of directories only in path1
* **rightDirs**: number of directories only in path2
* **differencesDirs**: total number of different directories (distinctDirs+leftDirs+rightDirs)
* **totalDirs**: total number of directories (differencesDirs+equalDirs)
* **brokenLinks**:
* **leftBrokenLinks**: number of broken links only in path1
* **rightBrokenLinks**: number of broken links only in path2
* **distinctBrokenLinks**: number of broken links with same name appearing in both path1 and path2
* **totalBrokenLinks**: total number of broken links (leftBrokenLinks+rightBrokenLinks+distinctBrokenLinks)
* **symlinks**: Statistics available if `compareSymlink` options is used
* **distinctSymlinks**: number of distinct links
* **equalSymlinks**: number of equal links
* **leftSymlinks**: number of links only in path1
* **rightSymlinks**: number of links only in path2
* **differencesSymlinks**: total number of different links (distinctSymlinks+leftSymlinks+rightSymlinks)
* **totalSymlinks**: total number of links (differencesSymlinks+equalSymlinks)
* **diffSet** - List of changes (present if `options.noDiffSet` is false)
* **path1**: path not including file/directory name; can be relative or absolute depending on call to compare(),
* **path2**: path not including file/directory name; can be relative or absolute depending on call to compare(),
* **relativePath**: path relative to root,
* **name1**: file/directory name
* **name2**: file/directory name
* **state**: one of equal, left, right, distinct,
* **type1**: one of missing, file, directory, broken-link
* **type2**: one of missing, file, directory, broken-link
* **size1**: file size
* **size2**: file size
* **date1**: modification date (stat.mtime)
* **date2**: modification date (stat.mtime)
* **level**: depth
* **reason**: Provides reason when two identically named entries are distinct.
Not available if entries are equal.
One of "different-size", "different-date", "different-content", "broken-link", "different-symlink".
Common options:
* [compareSize](https://gliviu.github.io/dc-api/interfaces/Options.html#compareSize)
* [compareContent](https://gliviu.github.io/dc-api/interfaces/Options.html#compareContent)
* [compareDate](https://gliviu.github.io/dc-api/interfaces/Options.html#compareDate)
* [excludeFilter](https://gliviu.github.io/dc-api/interfaces/Options.html#excludeFilter)
* [includeFilter](https://gliviu.github.io/dc-api/interfaces/Options.html#includeFilter)
* [ignoreCase](https://gliviu.github.io/dc-api/interfaces/Options.html#ignoreCase)
* [skipSubdirs](https://gliviu.github.io/dc-api/interfaces/Options.html#skipSubdirs)
* [skipEmptyDirs](https://gliviu.github.io/dc-api/interfaces/Options.html#skipEmptyDirs)
## Glob patterns
[Minimatch](https://www.npmjs.com/package/minimatch) patterns are used to include/exclude files to be compared.
@ -159,19 +105,46 @@ The pattern is matched against the relative path of the entry being compared.
Following examples assume we are comparing two [dir-compare](https://github.com/gliviu/dir-compare) code bases.
```javascript
const options = {
excludeFilter: ".git,node_modules", // exclude git and node modules directories
excludeFilter: "expected" , // exclude '/tests/expected' directory
excludeFilter: "/tests/expected" , // exclude '/tests/expected' directory
excludeFilter: "**/expected" , // exclude '/tests/expected' directory
excludeFilter: "**/tests/**/*.js" , // exclude all js files in '/tests' directory and subdirectories
includeFilter: "*.js,*.yml" , // include js and yaml files
includeFilter: "/tests/**/*.js" , // include all js files in '/tests' directory and subdirectories
includeFilter: "**/tests/**/*.ts" // include all js files in '/tests' directory and subdirectories
}
```
dircompare -x ".git,node_modules" dir1 dir2') exclude git and node modules directories
dircompare -x "expected" dir1 dir2') exclude '/tests/expected' directory
dircompare -x "/tests/expected" dir1 dir2') exclude '/tests/expected' directory
dircompare -x "**/expected" dir1 dir2') exclude '/tests/expected' directory
dircompare -x "**/tests/**/*.js" dir1 dir2') exclude all js files in '/tests' directory and subdirectories
dircompare -f "*.js,*.yml" dir1 dir2') include js and yaml files
dircompare -f "/tests/**/*.js" dir1 dir2') include all js files in '/tests' directory and subdirectories
dircompare -f "**/tests/**/*.ts" dir1 dir2') include all js files in '/tests' directory and subdirectories
```
This behavior can be changed with [Glob filter extensions](#glob-filter).
## Custom file content comparators
## Symbolic links
Unless `compareSymlink` option is used, symbolic links are resolved and any comparison is applied to the file/directory they point to.
Circular loops are handled by breaking the loop as soon as it is detected.
Version `1.x` treats broken links as `ENOENT: no such file or directory`.
Since `2.0` they are treated as a special type of entry - `broken-link` - and are available as stats (`totalBrokenLinks`, `distinctBrokenLinks`, ...).
Using `compareSymlink` option causes `dircompare` to check symlink values for equality.
In this mode two entries with identical names are considered different if
* one is symlink, the other is not
* both are symlinks but point to different locations
These rules are applied in addition to the other comparison modes; ie. by content, by size...
If entries are different because of symlinks, `reason` will be `different-symlink`. Also statistics summarize differences caused by symbolic links.
## Handling permission denied errors
Unreadable files or directories are normally reported as errors. The comparison will be interrupted with an `EACCES` exception.
This behavior can be altered with [Options.handlePermissionDenied](https://gliviu.github.io/dc-api/interfaces/Options.html#handlePermissionDenied).
# Extension points
## File content comparators
By default file content is binary compared. As of version 1.5.0 custom file comparison handlers may be specified.
Custom handlers are specified by `compareFileSync` and `compareFileAsync` options which correspond to `dircompare.compareSync()` or `dircompare.compare()` methods.
@ -182,37 +155,95 @@ A couple of handlers are included in the library:
* text sync compare - `dircompare.fileCompareHandlers.lineBasedFileCompare.compareSync`
* text async compare - `dircompare.fileCompareHandlers.lineBasedFileCompare.compareAsync`
Use [defaultFileCompare.js](https://github.com/gliviu/dir-compare/blob/master/src/fileCompareHandler/defaultFileCompare.js) as an example to create your own.
Use [defaultFileCompare](https://github.com/gliviu/dir-compare/blob/master/src/FileCompareHandler/default/defaultFileCompare.ts) as an example to create your own.
### Ignore line endings and white spaces
Line based comparator can be used to ignore line ending and white space differences. This comparator is not available in [CLI](#command-line) mode.
Line based comparator can be used to ignore line ending and white space differences.
```javascript
var dircompare = require('dir-compare');
const dircompare = require('dir-compare');
var options = {
const options = {
compareContent: true,
compareFileSync: dircompare.fileCompareHandlers.lineBasedFileCompare.compareSync,
compareFileAsync: dircompare.fileCompareHandlers.lineBasedFileCompare.compareAsync,
ignoreLineEnding: true,
ignoreWhiteSpaces: true
ignoreLineEnding: true, // Ignore crlf/lf line ending differences
ignoreWhiteSpaces: true, // Ignore white spaces at the beginning and end of a line (similar to 'diff -b')
ignoreAllWhiteSpaces: true, // Ignore all white space differences (similar to 'diff -w')
ignoreEmptyLines: true // Ignores differences caused by empty lines (similar to 'diff -B')
};
var path1 = '...';
var path2 = '...';
var res = dircompare.compareSync(path1, path2, options);
const path1 = '...';
const path2 = '...';
const res = dircompare.compareSync(path1, path2, options);
console.log(res)
dircompare.compare(path1, path2, options)
.then(res => console.log(res))
```
## Custom name comparators
If [default](https://github.com/gliviu/dir-compare/blob/master/src/nameCompare/defaultNameCompare.js) name comparison is not enough, custom behavior can be specified with [compareNameHandler](https://gliviu.github.io/dc-api/index.html#comparenamehandler) option.
## Glob filter
The current implementation of the glob filter uses minimatch and is based on [includeFilter and excludeFilter options](#glob-patterns). While it is meant to fit most use cases, [some scenarios](https://github.com/gliviu/dir-compare/issues/67) are not addressed.
Use [filterHandler option](https://gliviu.github.io/dc-api/interfaces/Options.html#filterHandler) to alter this behavior.
The following example demonstrates how to include only files with a specific extension in our comparison.
```typescript
import { Options, compareSync, Result, FilterHandler, Entry, filterHandlers } from 'dir-compare'
import { extname } from 'path'
var d1 = '...';
var d2 = '...';
const filterByfileExtension: FilterHandler = (entry: Entry, relativePath: string, options: Options): boolean => {
if (!options.fileExtension) {
// Fallback on the default 'minimatch' implementation
return filterHandlers.defaultFilterHandler(entry, relativePath, options)
}
return options.fileExtension === extname(entry.name)
}
const options: Options = {
compareSize: true,
fileExtension: '.txt',
filterHandler: filterByfileExtension
}
const res: Result = compareSync(d1, d2, options)
```
For reference, the default minimatch filter can be found in [defaultFilterHandler](https://github.com/gliviu/dir-compare/blob/master/src/FilterHandler/defaultFilterHandler.ts) which is exposed by [filterHandlers property](https://gliviu.github.io/dc-api/variables/filterHandlers.html).
### Implement .gitignore filter
[Globby](https://www.npmjs.com/package/globby) library provides the functionality to parse and apply `.gitignore` rules.
This is a [sample implementation](https://github.com/gliviu/dir-compare/blob/master/test/extended/gitignoreSupport/gitignoreFilter.ts) that uses globby and dir-compare filter extension.
Usage:
```typescript
import { Options, compareSync, Result} from 'dir-compare'
import { getGitignoreFilter } from './gitignoreFilter.js'
var d1 = '...';
var d2 = '...';
const options: Options = {
compareSize: true,
filterHandler: getGitignoreFilter(d1, d2),
includeFilter: '*.js' // if present, regular filters are applied after .gitignore rules.
}
const res: Result = compareSync(d1, d2, options)
```
## Name comparators
If [default](https://github.com/gliviu/dir-compare/blob/master/src/NameCompare/defaultNameCompare.ts) name comparison is not enough, custom behavior can be specified with [compareNameHandler](https://gliviu.github.io/dc-api/interfaces/Options.html#compareNameHandler) option.
Following example adds the possibility to ignore file extensions.
```typescript
import { Options, compare } from 'dir-compare'
import path from 'path'
var options: Options = {
const options: Options = {
compareSize: false, // compare only name by disabling size and content criteria
compareContent: false,
compareNameHandler: customNameCompare, // new name comparator used to ignore extensions
@ -231,10 +262,10 @@ function customNameCompare(name1: string, name2: string, options: Options) {
return ((name1 === name2) ? 0 : ((name1 > name2) ? 1 : -1))
}
var path1 = '/tmp/a';
var path2 = '/tmp/b';
const path1 = '/tmp/a';
const path2 = '/tmp/b';
var res = compare(path1, path2, options).then(res => {
const res = compare(path1, path2, options).then(res => {
console.log(`Same: ${res.same}`)
if (!res.diffSet) {
return
@ -246,108 +277,67 @@ var res = compare(path1, path2, options).then(res => {
// icon.svg icon.png equal
// logo.svg logo.jpg equal
```
For reference, the default name comparator can be found in [defaultNameCompare](https://github.com/gliviu/dir-compare/blob/master/src/NameCompare/defaultNameCompare.ts) which is exposed by [compareNameHandlers property](https://gliviu.github.io/dc-api/variables/compareNameHandlers.html).
## Custom result builder
[Result builder](https://gliviu.github.io/dc-api/index.html#resultbuilder) is called for each pair of entries encountered during comparison. Its purpose is to append entries in `diffSet` and eventually update `statistics` object with new stats.
## Result builder
[Result builder](https://gliviu.github.io/dc-api/interfaces/Options.html#resultBuilder) is called for each pair of entries encountered during comparison. Its purpose is to append entries in `diffSet` and eventually update `statistics` object with new stats.
If needed it can be replaced with custom implementation.
```javascript
var dircompare = require("dircompare")
const dircompare = require("dircompare")
var customResultBuilder = function (entry1, entry2, state, level, relativePath, options, statistics, diffSet, reason) {
const customResultBuilder = function (entry1, entry2, state, level, relativePath, options, statistics, diffSet, reason) {
...
}
var options = {
const options = {
compareSize: true,
resultBuilder: customResultBuilder
}
var res = dircompare.compareSync('...', '...', options)
const res = dircompare.compareSync('...', '...', options)
```
The [default](https://github.com/gliviu/dir-compare/blob/master/src/resultBuilder/defaultResultBuilderCallback.js) builder can be used as an example.
The [default](https://github.com/gliviu/dir-compare/blob/master/src/ResultBuilder/defaultResultBuilderCallback.ts) builder can be used as an example.
## Symbolic links
Unless `compareSymlink` option is used, symbolic links are resolved and any comparison is applied to the file/directory they point to.
Circular loops are handled by breaking the loop as soon as it is detected.
Version `1.x` treats broken links as `ENOENT: no such file or directory`.
Since `2.0` they are treated as a special type of entry - `broken-link` - and are available as stats (`totalBrokenLinks`, `distinctBrokenLinks`, ...).
Using `compareSymlink` option causes `dircompare` to check symlink values for equality.
In this mode two entries with identical name are considered different if
* one is symlink, the other is not
* both are symlinks but point to different locations
These rules are applied in addition to the other comparison modes; ie. by content, by size...
If entries are different because of symlinks, `reason` will be `different-symlink`. Also statistics summarizes differences caused by symbolik links.
# Command line
```
Usage: dircompare [options] leftdir rightdir
Options:
-h, --help output usage information
-V, --version output the version number
-c, --compare-content compare files by content
-D, --compare-date compare files by date
--date-tolerance [type] tolerance to be used in date comparison (milliseconds)
--compare-symlink compare files and directories by symlink
-f, --filter [type] file name filter
-x, --exclude [type] file/directory name exclude filter
-S, --skip-subdirs do not recurse into subdirectories
-L, --skip-symlinks ignore symlinks
-i, --ignore-case ignores case when comparing file names
-l, --show-left report - show entries occurring in left dir
-r, --show-right report - show entries occurring in right dir
-e, --show-equal report - show identic entries occurring in both dirs
-d, --show-distinct report - show distinct entries occurring in both dirs
-a, --show-all report - show all entries
-w, --whole-report report - include directories in detailed report
--reason report - show reason when entries are distinct
--csv report - print details as csv
--nocolors don't use console colors
--async Make use of multiple cores
By default files are compared by size.
--date-tolerance defaults to 1000 ms. Two files are considered to have
the same date if the difference between their modification dates fits
within date tolerance.
Exit codes:
0 - entries are identical
1 - entries are different
2 - error occurred
Examples:
compare by content dircompare -c dir1 dir2
show only different files dircompare -d dir1 dir2
exclude filter dircompare -x ".git,node_modules" dir1 dir2
dircompare -x "/tests/expected" dir1 dir2
dircompare -x "**/expected" dir1 dir2
dircompare -x "**/tests/**/*.ts" dir1 dir2
include filter dircompare -f "*.js,*.yml" dir1 dir2
dircompare -f "/tests/**/*.js" dir1 dir2
dircompare -f "**/tests/**/*.ts" dir1 dir2
```
# UI tools
* [dir-compare-cli](https://github.com/gliviu/dir-compare-cli)
* [Visual Studio Code - Compare Folders](https://marketplace.visualstudio.com/items?itemName=moshfeu.compare-folders)
# Changelog
* v2.4.0 New option to customize file/folder name comparison
* v4.2.0
* Updated dependencies
* Increased test coverage
* v4.1.0
* Possibility to alter the default [Glob filter](#glob-filter) behavior
* [Ignore files and directories according to .gitignore rules](#implement-gitignore-filter).
* New [origin](https://gliviu.github.io/dc-api/interfaces/Entry.html#origin) field in Entry to distinguish between the left or right directory
* Improved api documentation
* v4.0.0
* Switched project to typescript
* [Async comparator](https://gliviu.github.io/dc-api/functions/compare.html) improvements when comparing large directory structures
* Heap usage has decreased 3x compared to previous version
* Works 2x faster when comparing by content
* Better concurrency. UI apps will be more responsive while comparison is ongoing
Breaking changes:
* Using this library to compare two files will ignore the name of the files. More details in [#48](https://github.com/gliviu/dir-compare/issues/48)
* Removed support for node 8, 9
* v3.3.0 Added `skipEmptyDirs` option
* v3.2.0 [Handle permission denied errors](#handling-permission-denied-errors)
* v3.1.0 Added `ignoreAllWhiteSpaces` and `ignoreEmptyLines` options
* v3.0.0 Moved CLI component into separate project [dir-compare-cli](https://github.com/gliviu/dir-compare-cli)
* v2.4.0 [New option](https://gliviu.github.io/dc-api/interfaces/Options.html#compareNameHandler) to customize file/folder name comparison
* v2.3.0 Fixes
* v2.1.0 Removed [bluebird](https://github.com/petkaantonov/bluebird/#note) dependency
* v2.1.0 Removed [bluebird](https://github.com/petkaantonov/bluebird/#%EF%B8%8Fnote%EF%B8%8F) dependency
* v2.0.0
* New option to compare symlinks.
* New field indicating reason for two entries being distinct.
* Improved command line output format.
* Tests are no longer part of published package.
* Generated [Api](#api) documentation.
* Generated [Api](https://gliviu.github.io/dc-api) documentation.
Breaking changes:
* Broken links are no longer treated as errors. As a result there are new statistics (leftBrokenLinks, rightBrokenLinks, distinctBrokenLinks, totalBrokenLinks) and new entry type - broken-link.
@ -366,9 +356,10 @@ If entries are different because of symlinks, `reason` will be `different-symlin
* detect symlink loops
* improved color scheme for command line utility
* v1.0.0
* asynchronous processing
* asynchronous comparison
* new library options: noDiffSet, resultBuilder
* new statistics: distinctFiles, equalFiles, leftFiles, rightFiles, distinctDirs, equalDirs, leftDirs, rightDirs
* new --async command line option
* Fix for https://github.com/tj/commander.js/issues/125
* v0.0.3 Fix fille ordering issue for newer node versions
* v0.0.3 Fix file ordering issue for newer node versions