Skip to content

Implement file watcher for hot-reloading and command execution #4

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 20, 2024
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
18 changes: 18 additions & 0 deletions .vscode/cody.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"write-pull-request": {
"description": "Write a pull request for current changes",
"prompt": "Generate a pull request description based on the message provided. The pull request description has three sections: What happened, Insight, and Proof Of Work.\n\n- What happened section provides a brief review and concise description of the changes introduced by the pull request. Below is the format of this section (delimited by triple backticks):\n\n```\n## What happened 👀\n\n- Issue: [Issue number, e.g., #1]\n\nThis PR aims to [concisely describe the changes introduced by the PR]. The main changes include:\n\n- [Change 1]\n- [Change 2]\n- ...\n```\n\n- Insight section explains the rationale behind the chosen solution and why it is the most appropriate approach. When appropriate, consider using Mermaid script to create flowcharts or diagrams that visually represent the changes or the logic flow. Below is the format of this section (delimited by triple backticks):\n\n```\n## Insight 📝\nExplain the rationale behind the chosen solution and why it is the most appropriate approach. \n```\n\n- Proof Of Work section is left blank. Simply add the following text: \"## Proof Of Work 📹\"\n\nYour goal is to encourage self-reliance and comprehension through interactive support to generate the pull request description, aim for clarity, conciseness, and thoroughness in explaining the changes, the reasoning behind them. The description should provide reviewers with a comprehensive understanding of the pull request's purpose and impact. Use simple and straightfoward words, don't overuse buzz words or too fancy words. Keep it concise.\n\nUse these steps for generating description:\n- Get the required information: Ask the user to provide the purpose of the pull request and the issue number first before generating the description.\n- Foster Dialogue: Encourage the user to share thoughts, adapting your guidance based on their feedback while maintaining a supportive tone.\n- When you have all the information, generate the pull request description using the provided template.\n\nEnsure wrapping the generated pull request description in a markdown code block with sixth backticks (```)",
"mode": "ask",
"context": {
"codebase": false,
"command": "scripts/git-diff.sh",
"currentDir": false,
"currentFile": false,
"directoryPath": "",
"filePath": "",
"none": false,
"openTabs": false,
"selection": false
}
},
}
25 changes: 25 additions & 0 deletions scripts/git-diff.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/bash

# Get the current branch name
current_branch=$(git rev-parse --abbrev-ref HEAD)

# Get the previous branch name from reflog
previous_branch=$(git reflog | grep -m 1 'checkout: moving' | awk '{print $6}')

# Count the number of commits
commit_count=$(git rev-list --count $previous_branch..$current_branch)

# Generate the summary message
echo "The current branch $current_branch branch contains $commit_count commits that have been added since branching from $previous_branch."

# Loop through each commit and append details to the file
git log $previous_branch..$current_branch --format="%h" | while read commit_hash; do
# Append the commit message with the shorthand hash
echo "Commit: $commit_hash"
git log --pretty=format:"%B" -n 1 $commit_hash
echo ""

# Print the diff
git diff $commit_hash^!
echo ""
done
17 changes: 17 additions & 0 deletions src/constants/cody.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,24 @@
import * as path from 'path'
import * as vscode from 'vscode'

export const CODY_COMMAND = {
MENTION: {
FILE: 'cody.mention.file'
},
COMMAND: {
CUSTOM: 'cody.command.custom'
}
}

export const CODY_CUSTOM_COMMANDS_FILE = 'cody.json'

export function getCodyJsonPath(): string | undefined {
const workspaceFolders = vscode.workspace.workspaceFolders
if (!workspaceFolders) {
console.error('CODY++: No workspace folder is open.')
return undefined
}

const vscodeFolderPath = path.join(workspaceFolders[0].uri.fsPath, '.vscode')
return path.join(vscodeFolderPath, CODY_CUSTOM_COMMANDS_FILE)
}
6 changes: 5 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,8 @@ export function activate(context: vscode.ExtensionContext) {
)
}

export function deactivate() {}
export function deactivate() {
if (CustomCommandService && CustomCommandService.getInstance()) {
CustomCommandService.getInstance().disposeFileWatcher()
}
}
47 changes: 31 additions & 16 deletions src/services/customCommand.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as fs from 'fs'
import * as path from 'path'
import * as vscode from 'vscode'

import { z } from 'zod'
import { CODY_CUSTOM_COMMANDS_FILE } from '../constants/cody'
import { CODY_CUSTOM_COMMANDS_FILE, getCodyJsonPath } from '../constants/cody'

export const CustomCommandId = z.string()

Expand Down Expand Up @@ -48,11 +47,13 @@ type CustomCommands = z.infer<typeof CustomCommandsSchema>
export class CustomCommandService {
private static instance: CustomCommandService
private commands: CustomCommands = {}
private fileWatcher: vscode.FileSystemWatcher | undefined
private _onDidChangeCommands: vscode.EventEmitter<void> = new vscode.EventEmitter<void>()
public readonly onDidChangeCommands: vscode.Event<void> = this._onDidChangeCommands.event

private constructor() {
this.loadCommands()
this.setupFileWatcher()
}

public static getInstance(): CustomCommandService {
Expand All @@ -63,15 +64,12 @@ export class CustomCommandService {
}

private async loadCommands() {
const workspaceFolders = vscode.workspace.workspaceFolders
if (!workspaceFolders) {
console.error('CODY++: No workspace folder is open.')
const codyJsonPath = getCodyJsonPath()

if (!codyJsonPath) {
return
}

const vscodeFolderPath = path.join(workspaceFolders[0].uri.fsPath, '.vscode')
const codyJsonPath = path.join(vscodeFolderPath, CODY_CUSTOM_COMMANDS_FILE)

try {
const fileContent = await fs.promises.readFile(codyJsonPath, 'utf-8')
const parsedCommands = JSON.parse(fileContent)
Expand All @@ -84,12 +82,33 @@ export class CustomCommandService {
}

this.commands = validationResult.data
this._onDidChangeCommands.fire()
this._onDidChangeCommands?.fire()
} catch (error: any) {
console.error(`CODY++: Failed to load ${CODY_CUSTOM_COMMANDS_FILE}: ${error.message}`)
}
}

private setupFileWatcher() {
const codyJsonPath = getCodyJsonPath()

if (!codyJsonPath) {
return
}

this.fileWatcher = vscode.workspace.createFileSystemWatcher(codyJsonPath)

this.fileWatcher.onDidChange(() => this.loadCommands())
this.fileWatcher.onDidCreate(() => this.loadCommands())
this.fileWatcher.onDidDelete(() => this.loadCommands())
}

public disposeFileWatcher() {
if (this.fileWatcher) {
this.fileWatcher.dispose()
this.fileWatcher = undefined
}
}

public getCommands(): CustomCommands {
return this.commands
}
Expand All @@ -106,7 +125,6 @@ export class CustomCommandService {

public async updateCommand({ id, oldId, data }: UpdateCustomCommand): Promise<void> {
// If id !== oldId, we need to delete the old command and add the new one
console.log(id, oldId)
if (oldId && id !== oldId) {
await this.removeCommand(oldId)
await this.addCommand(id, data)
Expand All @@ -129,15 +147,12 @@ export class CustomCommandService {
}

private async saveCommands(): Promise<void> {
const workspaceFolders = vscode.workspace.workspaceFolders
if (!workspaceFolders) {
console.error('CODY++: No workspace folder is open.')
const codyJsonPath = getCodyJsonPath()

if (!codyJsonPath) {
return
}

const vscodeFolderPath = path.join(workspaceFolders[0].uri.fsPath, '.vscode')
const codyJsonPath = path.join(vscodeFolderPath, `${CODY_CUSTOM_COMMANDS_FILE}`)

try {
const fileContent = JSON.stringify(this.commands, null, 2)
await fs.promises.writeFile(codyJsonPath, fileContent, 'utf-8')
Expand Down
8 changes: 7 additions & 1 deletion src/views/CustomCommandsTreeView.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as vscode from 'vscode'
import z from 'zod'
import { CODY_COMMAND } from '../constants/cody'
import { CustomCommandService, CustomCommandsSchema } from '../services/customCommand.service'

interface CommandTreeItem extends vscode.TreeItem {
Expand Down Expand Up @@ -53,7 +54,12 @@ export class CustomCommandsTreeView implements vscode.TreeDataProvider<CommandTr
commandId: commandId,
collapsibleState: vscode.TreeItemCollapsibleState.None,
iconPath: iconPath,
contextValue: 'customCommand'
contextValue: 'customCommand',
command: {
title: `Execute ${commandId}`,
command: `${CODY_COMMAND.COMMAND.CUSTOM}.${commandId}`,
arguments: [commandId]
}
} as CommandTreeItem
})
}
Expand Down
1 change: 0 additions & 1 deletion src/views/CustomCommandsWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ export class CustomCommandsWebview {
this._createCommand(message)
break
case COMMANDS.UPDATE_COMMAND:
console.log(message)
this._updateCommand(message)
break
// Add more cases here to handle other commands
Expand Down