Skip to content

Commit

Permalink
Merge pull request #2 from h-sphere/feat/snapshot
Browse files Browse the repository at this point in the history
feat: ability to save snapshots
  • Loading branch information
kulak-at authored Aug 10, 2024
2 parents a5aac39 + 25ca5fe commit 6401c1b
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules/
symplectic.txt
.symplecticarchive
59 changes: 59 additions & 0 deletions LLM.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Symplectic Format Instructions for LLM

When responding to queries about file structures or content, always use the Symplectic format. This format allows for precise specification of file content, including creation, modification, prepending, and appending. Adhere to these guidelines meticulously:

1. File Separator and Path:
- Begin each file entry with `//||` followed by a space and the full file path from the project root.
- Example: `//|| src/main.js`

2. File Content:
- Immediately after the file separator line, write the entire content of the file.
- Do not add any extra newlines between the separator and the content.

3. Creating or Overwriting Files:
- Use `//||` for new files or when overwriting existing files.
- Include the complete content of the file.

4. Prepending Content:
- Use `//||^` to prepend content to an existing file.
- Example: `//||^ README.md`
- Only include the new content to be prepended, not the existing file content.

5. Appending Content:
- Use `//||$` to append content to an existing file.
- Example: `//||$ config.json`
- Only include the new content to be appended, not the existing file content.

6. Multiple Files:
- Separate different file entries with a single blank line.

7. Full File Modifications:
- For files that are modified (not just prepended or appended), use `//||` and include the entire new content of the file.

Critical Rules:
- Always use the correct separator (`//||`, `//||^`, or `//||$`) for each operation.
- Include the full path for each file, starting from the project root.
- For prepend (`//||^`) and append (`//||$`) operations, include only the new content.
- For full file modifications or new files, include the entire content.
- Do not use any Markdown formatting or code blocks within the Symplectic format.

Example of a well-formed Symplectic format response:
```
//|| src/main.js
console.log('Hello, Symplectic!');
//||^ README.md
# Project Title
This content will be prepended to the existing README.
//||$ config.json
,
"newSetting": "value"
}
//|| docs/guide.md
# User Guide
This is a new file with complete content.
Remember: Always use this format for responses involving file structures or content. Maintain consistency and precision in your use of separators and content inclusion.
```
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Symplectic

Symplectic is a Node.js utility for managing project structures through a single file. It allows you to generate a `symplectic.txt` file from an existing project structure, create project structures from a `symplectic.txt` file, and remove files based on the `symplectic.txt` specification. Additionally, it supports prepending and appending content to existing files.
Symplectic is a Node.js utility for managing project structures through a single file. It allows you to generate a `symplectic.txt` file from an existing project structure, create project structures from a `symplectic.txt` file, remove files based on the `symplectic.txt` specification, and now includes a snapshot feature for easy reverting of changes.

## Use Cases

Expand All @@ -14,6 +14,8 @@ Symplectic is a Node.js utility for managing project structures through a single

5. **File Modification**: Prepend or append content to existing files without overwriting them.

6. **Version Control**: Create snapshots of your project structure for easy reverting of changes.

## Important Disclaimer

**Warning**: The operations performed by Symplectic are destructive by nature. Always archive your changes and use version control. It is strongly recommended to operate in dry-run mode first to verify the intended actions. The author does not take any responsibility for data loss caused by the use of this tool.
Expand Down Expand Up @@ -115,6 +117,21 @@ If the dry run output looks correct, run without `--dry-run` to apply the change
symplectic
```

### Create a Snapshot

To apply changes and create a snapshot of the resulting system state:

```bash
symplectic --save-snapshot
```

This command will:
1. Apply all changes specified in the `symplectic.txt` file.
2. Create a snapshot of the resulting system state after the changes have been applied.
3. Save the snapshot in the `.symplecticarchive` directory with a timestamp in the filename.

The snapshot file will be in the Symplectic format, allowing you to revert to this state later if needed.

## Parameters

Symplectic supports the following command-line parameters:
Expand All @@ -126,6 +143,7 @@ Symplectic supports the following command-line parameters:
| `--remove` | `-r` | Remove files instead of creating them |
| `--generate` | `-g` | Generate symplectic.txt file from existing structure |
| `--subfolder <path>` | `-s <path>` | Generate structure for a specific subfolder |
| `--save-snapshot` | `-S` | Apply changes and save a snapshot of the resulting system |
| `--help` | `-h` | Show help information |

## Examples
Expand Down Expand Up @@ -162,6 +180,12 @@ Symplectic supports the following command-line parameters:
symplectic --dry-run
```

6. Apply changes and create a snapshot:

```bash
symplectic --save-snapshot
```

## .symplecticignore

Symplectic respects `.gitignore` rules and also supports a `.symplecticignore` file for additional exclusions. The `symplectic.txt` file itself is always ignored.
Expand Down
70 changes: 68 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ const argv = yargs
type: 'string',
description: 'Generate structure for a specific subfolder'
})
.option('save-snapshot', {
alias: 'S',
type: 'boolean',
description: 'Apply changes and save a snapshot of the resulting system'
})
.help()
.alias('help', 'h')
.argv;
Expand Down Expand Up @@ -65,7 +70,60 @@ function appendToFile(filePath, content) {
log(`Appended to file: ${filePath}`);
}

function applyChangesAndSaveSnapshot(inputFilePath) {
const archiveDir = path.join(process.cwd(), '.symplecticarchive');
if (!fs.existsSync(archiveDir)) {
fs.mkdirSync(archiveDir);
}

const timestamp = new Date().toISOString().replace(/[-:]/g, '').replace(/\..+/, '');
const snapshotPath = path.join(archiveDir, `${timestamp}.txt`);

const content = fs.readFileSync(inputFilePath, 'utf8');
const sections = content.split(`\n${SEPARATOR} `);

let snapshotContent = '';

sections.forEach((section) => {
let [header, ...fileContent] = section.split('\n');
if (header.startsWith(SEPARATOR)) {
header = header.slice(SEPARATOR.length);
}
const { modifier, filename } = detectModifier(header);
const filePath = path.join(process.cwd(), filename);
const content = fileContent.join('\n');

// Apply changes
const directoryPath = path.dirname(filePath);
fs.mkdirSync(directoryPath, { recursive: true });

switch (modifier) {
case 'prepend':
prependToFile(filePath, content);
break;
case 'append':
appendToFile(filePath, content);
break;
default:
fs.writeFileSync(filePath, content);
log(`Created/Updated file: ${filePath}`);
}

// Read the final content for the snapshot
const finalContent = fs.readFileSync(filePath, 'utf8');
snapshotContent += `${SEPARATOR} ${filename}\n${finalContent}\n\n`;
});

fs.writeFileSync(snapshotPath, snapshotContent.trim());
log(`Changes applied and snapshot saved: ${snapshotPath}`);
}

function processInputFile(inputFilePath) {
if (argv.saveSnapshot) {
applyChangesAndSaveSnapshot(inputFilePath);
return;
}

const content = fs.readFileSync(inputFilePath, 'utf8');
const sections = content.split(`\n${SEPARATOR} `);

Expand Down Expand Up @@ -182,11 +240,19 @@ function main() {

try {
log(`Processing input file: ${inputFile}`);
log(argv.dryRun ? 'Performing dry run...' : (argv.remove ? 'Removing files...' : 'Creating/updating files...'));
if (argv.saveSnapshot) {
log('Applying changes and saving snapshot...');
} else {
log(argv.dryRun ? 'Performing dry run...' : (argv.remove ? 'Removing files...' : 'Creating/updating files...'));
}

processInputFile(inputFile);

console.log(`Files ${argv.dryRun ? 'would be' : 'were'} ${argv.remove ? 'removed' : 'created/updated'} successfully from ${inputFile}`);
if (!argv.saveSnapshot) {
console.log(`Files ${argv.dryRun ? 'would be' : 'were'} ${argv.remove ? 'removed' : 'created/updated'} successfully from ${inputFile}`);
} else {
console.log('Changes applied and snapshot saved successfully');
}
} catch (error) {
console.error(`Error: ${error.message}`);
process.exit(1);
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "symplectic",
"version": "0.0.2",
"version": "0.0.3",
"description": "",
"main": "index.js",
"scripts": {
Expand Down

0 comments on commit 6401c1b

Please sign in to comment.