Skip to content

Commit

Permalink
feat: add .aitkignore file
Browse files Browse the repository at this point in the history
  • Loading branch information
markwylde committed Jul 31, 2024
1 parent c4e4a1e commit 6d5c179
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 15 deletions.
30 changes: 25 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ npm install -g @markwylde/ai-toolkit
## Usage

```bash
aitk [command] [directory]
aitk [command] [directory1] [directory2] ...
```

### Commands
Expand All @@ -35,17 +35,37 @@ aitk [command] [directory]

2. Dump contents of all files in a specific directory:
```bash
aitk cat
aitk cat /path/to/directory
```

3. Show help message:
3. List files in multiple directories:
```bash
aitk ls /path/to/dir1 /path/to/dir2
```

4. Show help message:
```bash
aitk help
```

## Features

- Recursively lists files in a directory
- Ignores specified files and directories (e.g., `.git`, `node_modules`)
- Ignores files with specific extensions (e.g., `png`, `svg`, `jpg`)
- Supports multiple directory inputs
- Uses .aitkignore files for custom ignoring rules
- Supports a global ~/.aitkignore file for system-wide ignore rules
- Dumps file contents with file paths as headers
- Displays directory structure with tree-like formatting

## Ignore Rules

You can create a `.aitkignore` file in any directory to specify ignore rules. Additionally, a global `~/.aitkignore` file can be used for system-wide ignore rules. The syntax is similar to `.gitignore` files.

Example `.aitkignore` file:
```
node_modules
*.log
build/
```

This will ignore the `node_modules` directory, all files with the `.log` extension, and the `build` directory.
59 changes: 49 additions & 10 deletions bin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,64 @@
import fs from 'fs';
import path from 'path';
import minimist from 'minimist';
import os from 'os';
import ignore from 'ignore';

// Read the global ~/.aitkignore file once at the start
const homeAitkignorePath = path.join(os.homedir(), '.aitkignore');
let globalIgnoreRules = [];
try {
if (fs.existsSync(homeAitkignorePath)) {
globalIgnoreRules = fs.readFileSync(homeAitkignorePath, 'utf8').split('\n').filter(line => line.trim() !== '');
}
} catch (err) {
console.error(`Error reading global .aitkignore file: ${err.message}`);
}

const ignore = ['.next', '.husky', '.terraform.lock.hcl', '.terraform', '.git', '.DS_Store', 'node_modules', 'package-lock.json', 'coverage'];
const ignoreExtensions = ['png', 'svg', 'jpg', 'jpeg', 'bin', 'stories.tsx'];
// Function to find the closest .aitkignore file
function findClosestAitkignore(dir) {
let currentDir = dir;
while (currentDir !== path.parse(currentDir).root) {
const aitkignorePath = path.join(currentDir, '.aitkignore');
if (fs.existsSync(aitkignorePath)) {
return aitkignorePath;
}
currentDir = path.dirname(currentDir);
}
return null;
}

// Function to read and parse .aitkignore files
function parseAitkignore(aitkignorePath) {
if (!aitkignorePath) return [];
try {
return fs.readFileSync(aitkignorePath, 'utf8').split('\n').filter(line => line.trim() !== '');
} catch (err) {
console.error(`Error reading .aitkignore file: ${err.message}`);
return [];
}
}

// Function to list all files recursively
function listFiles(dir, dumpContent = false, output = '', baseDir = '', depth = 0) {
const files = fs.readdirSync(dir, {
withFileTypes: true
});
const closestAitkignore = findClosestAitkignore(dir);

const ignoreRules = [
...parseAitkignore(closestAitkignore),
...globalIgnoreRules
];

const ig = ignore().add(ignoreRules);

const files = fs.readdirSync(dir, { withFileTypes: true });
files.forEach((file, index) => {
const fileNameParts = file.name.split('.');
const ext = fileNameParts.length > 1 ? fileNameParts.slice(-2).join('.') : fileNameParts[fileNameParts.length - 1];
const filePath = path.join(dir, file.name);
const relativePath = path.relative(process.cwd(), filePath);

if (ignore.includes(file.name) || ignoreExtensions.includes(ext)) {
if (ig.ignores(relativePath)) {
return;
}

const filePath = path.join(dir, file.name);
const relativePath = path.join(baseDir, path.relative(dir, filePath));
const isLast = index === files.length - 1;
const prefix = depth === 0 ? '' : ' '.repeat(depth - 1) + (isLast ? '└─ ' : '├─ ');

Expand Down
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"license": "MIT",
"description": "A set of utilities for working with ai tools",
"dependencies": {
"ignore": "^5.3.1",
"minimist": "^1.2.8"
}
}

0 comments on commit 6d5c179

Please sign in to comment.