Skip to content

Commit

Permalink
Merge pull request #13 from yamadashy/feature/repopackignore
Browse files Browse the repository at this point in the history
Add support for .repopackignore and enhance ignore pattern documentation
  • Loading branch information
yamadashy authored Jul 27, 2024
2 parents 91c9fed + 002c76f commit 80702fc
Show file tree
Hide file tree
Showing 9 changed files with 149 additions and 89 deletions.
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ Create a `repopack.config.json` file in your project root for custom configurati
|`output.removeEmptyLines`| Whether to remove empty lines from the output | `false` |
|`output.topFilesLength`| Number of top files to display in the summary. If set to 0, no summary will be displayed |`5`|
|`output.showLineNumbers`| Whether to add line numbers to each line in the output |`false`|
|`ignore.useGitignore`| Whether to use patterns from the project's `.gitignore` file |`true`|
|`ignore.useDefaultPatterns`| Whether to use default ignore patterns |`true`|
|`ignore.customPatterns`| Additional patterns to ignore |`[]`|

Expand All @@ -162,23 +163,28 @@ Example configuration:
"showLineNumbers": false
},
"ignore": {
"useGitignore": true,
"useDefaultPatterns": true,
"customPatterns": ["additional-folder", "*.log"]
}
}
```

### Default Ignore Patterns
### Ignore Patterns
Repopack offers multiple methods to set ignore patterns for excluding specific files or directories during the packing process:

Repopack automatically ignores certain files and directories by default:
- **.gitignore**: By default, patterns listed in your project's `.gitignore` file are used. This behavior can be controlled with the `ignore.useGitignore` setting.
- **Default patterns**: Repopack includes a default list of commonly excluded files and directories (e.g., node_modules, .git, binary files). This feature can be controlled with the `ignore.useDefaultPatterns` setting. Please see [defaultIgnore.ts](src/utils/defaultIgnore.ts) for more details.
- **.repopackignore**: You can create a `.repopackignore` file in your project root to define Repopack-specific ignore patterns. This file follows the same format as `.gitignore`.
- **Custom patterns**: Additional ignore patterns can be specified using the `ignore.customPatterns` option in the configuration file. You can overwrite this setting with the `-i, --ignore` command line option.

- All patterns specified in your project's `.gitignore` file
- Git-related files and directories (e.g., `.git`, `.gitattributes`)
- Binary files (e.g., images, executables)
- Common build output and dependency directories (e.g., `node_modules`, `dist`)
- System and IDE-specific files (e.g., `.DS_Store`, `.vscode`)
Priority Order (from highest to lowest):
1. Custom patterns `ignore.customPatterns`
2. `.repopackignore`
3. `.gitignore` (if `ignore.useGitignore` is true)
4. Default patterns (if `ignore.useDefaultPatterns` is true)

This ensures that only relevant source code is included in the packed file. You can add additional ignore patterns using the `ignore.customPatterns` configuration option or the `-i` command line flag.
This approach allows for flexible file exclusion configuration based on your project's needs. It helps optimize the size of the generated pack file by ensuring the exclusion of security-sensitive files and large binary files, while preventing the leakage of confidential information.

### Comment Removal

Expand Down
1 change: 1 addition & 0 deletions repopack.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"showLineNumbers": false
},
"ignore": {
"useGitignore": true,
"useDefaultPatterns": true,
"customPatterns": []
}
Expand Down
1 change: 1 addition & 0 deletions src/config/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const defaultConfig: RepopackConfigDefault = {
showLineNumbers: false,
},
ignore: {
useGitignore: true,
useDefaultPatterns: true,
customPatterns: [],
},
Expand Down
23 changes: 5 additions & 18 deletions src/core/packager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@ import type { SecretLintCoreResult } from '@secretlint/types';
import { RepopackConfigMerged } from '../types/index.js';
import { processFile as defaultProcessFile } from '../utils/fileHandler.js';
import {
getGitignorePatterns as defaultGetGitignorePatterns,
getAllIgnorePatterns as defaultGetAllIgnorePatterns,
createIgnoreFilter as defaultCreateIgnoreFilter,
IgnoreFilter,
} from '../utils/gitignoreUtils.js';
} from '../utils/ignoreUtils.js';
import { generateOutput as defaultGenerateOutput } from './outputGenerator.js';
import { defaultIgnoreList } from '../utils/defaultIgnore.js';
import { checkFileWithSecretLint, createSecretLintConfig } from '../utils/secretLintUtils.js';
import { logger } from '../utils/logger.js';

export interface Dependencies {
getGitignorePatterns: typeof defaultGetGitignorePatterns;
getAllIgnorePatterns: typeof defaultGetAllIgnorePatterns;
createIgnoreFilter: typeof defaultCreateIgnoreFilter;
processFile: typeof defaultProcessFile;
generateOutput: typeof defaultGenerateOutput;
Expand All @@ -36,15 +35,14 @@ export async function pack(
rootDir: string,
config: RepopackConfigMerged,
deps: Dependencies = {
getGitignorePatterns: defaultGetGitignorePatterns,
getAllIgnorePatterns: defaultGetAllIgnorePatterns,
createIgnoreFilter: defaultCreateIgnoreFilter,
processFile: defaultProcessFile,
generateOutput: defaultGenerateOutput,
},
): Promise<PackResult> {
// Get ignore patterns
const gitignorePatterns = await deps.getGitignorePatterns(rootDir);
const ignorePatterns = getIgnorePatterns(gitignorePatterns, config);
const ignorePatterns = await deps.getAllIgnorePatterns(rootDir, config);
const ignoreFilter = deps.createIgnoreFilter(ignorePatterns);

// Get all file paths in the directory
Expand Down Expand Up @@ -73,17 +71,6 @@ export async function pack(
};
}

function getIgnorePatterns(gitignorePatterns: string[], config: RepopackConfigMerged): string[] {
let ignorePatterns = [...gitignorePatterns];
if (config.ignore.useDefaultPatterns) {
ignorePatterns = [...ignorePatterns, ...defaultIgnoreList];
}
if (config.ignore.customPatterns) {
ignorePatterns = [...ignorePatterns, ...config.ignore.customPatterns];
}
return ignorePatterns;
}

async function getFilePaths(dir: string, relativePath: string, ignoreFilter: IgnoreFilter): Promise<string[]> {
const entries = await fs.readdir(dir, { withFileTypes: true });
const filePaths: string[] = [];
Expand Down
4 changes: 4 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ interface RepopackConfigBase {
showLineNumbers?: boolean;
};
ignore?: {
useGitignore?: boolean;
useDefaultPatterns?: boolean;
customPatterns?: string[];
};
Expand All @@ -23,6 +24,7 @@ export type RepopackConfigDefault = RepopackConfigBase & {
showLineNumbers: boolean;
};
ignore: {
useGitignore: boolean;
useDefaultPatterns: boolean;
customPatterns?: string[];
};
Expand All @@ -38,6 +40,7 @@ export type RepopackConfigFile = RepopackConfigBase & {
showLineNumbers?: boolean;
};
ignore?: {
useGitignore?: boolean;
useDefaultPatterns?: boolean;
customPatterns?: string[];
};
Expand All @@ -53,6 +56,7 @@ export type RepopackConfigCli = RepopackConfigBase & {
showLineNumbers?: boolean;
};
ignore?: {
useGitignore?: boolean;
useDefaultPatterns?: boolean;
customPatterns?: string[];
};
Expand Down
29 changes: 0 additions & 29 deletions src/utils/gitignoreUtils.ts

This file was deleted.

53 changes: 53 additions & 0 deletions src/utils/ignoreUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import * as fs from 'fs/promises';
import path from 'path';
import ignore from 'ignore';
import { logger } from './logger.js';
import { RepopackConfigMerged } from '../types/index.js';
import { defaultIgnoreList } from './defaultIgnore.js';

export async function getIgnorePatterns(filename: string, rootDir: string, fsModule = fs): Promise<string[]> {
const ignorePath = path.join(rootDir, filename);
try {
const ignoreContent = await fsModule.readFile(ignorePath, 'utf-8');
return parseIgnoreContent(ignoreContent);
} catch (error) {
logger.debug(`No ${filename} file found or unable to read it.`);
return [];
}
}

export function parseIgnoreContent(content: string): string[] {
return content
.split('\n')
.map((line) => line.trim())
.filter((line) => line && !line.startsWith('#'));
}

export type IgnoreFilter = (path: string) => boolean;

export function createIgnoreFilter(patterns: string[]): IgnoreFilter {
const ig = ignore.default().add(patterns);
return ig.createFilter();
}

export async function getAllIgnorePatterns(rootDir: string, config: RepopackConfigMerged): Promise<string[]> {
let ignorePatterns: string[] = [];

if (config.ignore.useDefaultPatterns) {
ignorePatterns = [...ignorePatterns, ...defaultIgnoreList];
}

const gitignorePatterns = await getIgnorePatterns('.gitignore', rootDir);
if (config.ignore.useGitignore) {
ignorePatterns = [...ignorePatterns, ...gitignorePatterns];
}

const repopackIgnorePatterns = await getIgnorePatterns('.repopackignore', rootDir);
ignorePatterns = [...ignorePatterns, ...repopackIgnorePatterns];

if (config.ignore.customPatterns) {
ignorePatterns = [...ignorePatterns, ...config.ignore.customPatterns];
}

return ignorePatterns;
}
5 changes: 4 additions & 1 deletion tests/core/packager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ describe('packager', () => {
beforeEach(() => {
vi.resetAllMocks();
mockDeps = {
getGitignorePatterns: vi.fn().mockResolvedValue([]),
getAllIgnorePatterns: vi.fn().mockResolvedValue([]),
createIgnoreFilter: vi.fn().mockReturnValue(() => true),
processFile: vi.fn().mockResolvedValue('processed content'),
generateOutput: vi.fn().mockResolvedValue(undefined),
Expand All @@ -36,6 +36,9 @@ describe('packager', () => {
expect(vi.mocked(fs.readdir).mock.calls[0][0]).toBe('root');
expect(vi.mocked(fs.readdir).mock.calls[1][0]).toBe(path.join('root', 'dir1'));

expect(mockDeps.getAllIgnorePatterns).toHaveBeenCalledWith('root', mockConfig);
expect(mockDeps.createIgnoreFilter).toHaveBeenCalled();
expect(mockDeps.processFile).toHaveBeenCalledTimes(2);
expect(mockDeps.generateOutput).toHaveBeenCalledWith('root', mockConfig, [
{ path: 'file1.txt', content: 'processed content' },
{ path: path.join('dir1', 'file2.txt'), content: 'processed content' },
Expand Down
Loading

0 comments on commit 80702fc

Please sign in to comment.