Skip to content

Commit

Permalink
aidda: skip timestamp check for new output files
Browse files Browse the repository at this point in the history
  • Loading branch information
stevegt committed Nov 9, 2024
1 parent 6897dea commit 781dd22
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 72 deletions.
2 changes: 1 addition & 1 deletion .aidda/prompt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
aidda: comment out everything related to the test subcommand
aidda: skip timestamp check for new output files

In:
v3/aidda/aidda.go
Expand Down
139 changes: 75 additions & 64 deletions .aidda/response
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ XXX update this

var (
baseDir string
promptFn string
ignoreFn string
testFn string
generateStampFn string
commitStampFn string
DefaultSysmsg = "You are an expert Go programmer. Please make the requested changes to the given code or documentation."
Expand Down Expand Up @@ -114,67 +116,21 @@ func Do(g *core.Grokker, args ...string) (err error) {
_, err = os.Stat(Spf("%s/.git", baseDir))
Ck(err)

// create a directory for aidda files
// XXX location might want to be more flexible
dir := Spf("%s/.aidda", baseDir)
err = os.MkdirAll(dir, 0755)
Ck(err)

// generate filenames
// XXX these should all be in a struct
promptFn := Spf("%s/prompt", dir)
promptFn = Spf("%s/prompt", dir)
ignoreFn = Spf("%s/ignore", dir)
testFn := Spf("%s/test", dir)
testFn = Spf("%s/test", dir)
generateStampFn = Spf("%s/generate.stamp", dir)
commitStampFn = Spf("%s/commit.stamp", dir)

// Ensure there is an ignore file
err = ensureIgnoreFile(ignoreFn)
Ck(err)

// Initialize Stamp instances for generate and commit
// Initialize Stamp objects for generate and commit
generateStamp = NewStamp(generateStampFn)
commitStamp = NewStamp(commitStampFn)

// Ensure timestamp files exist
now := time.Now()
err = generateStamp.Ensure(now)
Ck(err)
err = commitStamp.Ensure(now)
Ck(err)

// If the test file is newer than any input files, then include
// the test results in the prompt; otherwise, clear the test file
testResults := ""
testStat, err := os.Stat(testFn)
if os.IsNotExist(err) {
err = nil
} else {
Ck(err)
// Get the list of input files
p, err := getPrompt(promptFn)
Ck(err)
inFns := p.In
// Check if the test file is newer than any input files
for _, fn := range inFns {
inStat, err := os.Stat(fn)
Ck(err)
if testStat.ModTime().After(inStat.ModTime()) {
// Include the test results in the prompt
buf, err := os.ReadFile(testFn)
Ck(err)
testResults = string(buf)
break
}
}
}
if len(testResults) == 0 {
// Clear the test file
Pl("Clearing test file")
err = os.WriteFile(testFn, []byte{}, 0644)
Ck(err)
}

// Determine if interactive mode is active
isInteractive := false
for _, cmd := range args {
Expand All @@ -184,20 +140,20 @@ func Do(g *core.Grokker, args ...string) (err error) {
}
}

// Refactored loop: consume (shift) subcommands from args
// consume subcommands from args
for len(args) > 0 {
cmd := args[0]
args = args[1:]
Pl("aidda: running subcommand", cmd)
switch cmd {
case "init":
err = mkPrompt(promptFn)
err = initAidda(dir)
Ck(err)
case "menu":
action, err := menu(g)
Ck(err)
// Push the selected action to the args slice
args = append(args, action)
// Push the selected action to the front of args
args = append([]string{action}, args...)
case "commit":
// Check if prompt is newer than generate.stamp
promptIsNewer, err := generateStamp.OlderThan(promptFn)
Expand Down Expand Up @@ -238,14 +194,14 @@ func Do(g *core.Grokker, args ...string) (err error) {
var p *Prompt
p, err = getPrompt(promptFn)
Ck(err)
err = generate(g, p, testResults)
err = generate(g, p)
Ck(err)
case "regenerate":
// Regenerate code from the prompt without committing
var p *Prompt
p, err = getPrompt(promptFn)
Ck(err)
err = generate(g, p, testResults)
err = generate(g, p)
Ck(err)
case "force-commit":
// Commit using the current promptFn without checking
Expand Down Expand Up @@ -292,7 +248,7 @@ func Do(g *core.Grokker, args ...string) (err error) {
case "abort":
// Abort the current operation
Pl("Operation aborted by user.")
return fmt.Errorf("operation aborted")
return nil
default:
PrintUsageAndExit()
}
Expand All @@ -305,7 +261,7 @@ func PrintUsageAndExit() {
fmt.Println("Usage: go run main.go {subcommand ...}")
fmt.Println("Subcommands:")
fmt.Println(" menu - Display the action menu")
fmt.Println(" init - Initialize the prompt file")
fmt.Println(" init - Initialize the .aidda directory")
fmt.Println(" commit - Commit using the current prompt file contents as the commit message")
fmt.Println(" generate - Generate changes from GPT based on the prompt")
fmt.Println(" regenerate - Regenerate code from the prompt without committing")
Expand All @@ -324,13 +280,29 @@ type Prompt struct {
Txt string
}

// mkPrompt function is responsible for creating a prompt file.
func mkPrompt(path string) (err error) {
// initAidda function is responsible for creating the .aidda directory and its contents
func initAidda(dir string) (err error) {
defer Return(&err)

// create a directory for aidda files
err = os.MkdirAll(dir, 0755)
Ck(err)

// Ensure there is an ignore file
err = ensureIgnoreFile(ignoreFn)
Ck(err)

// Ensure timestamp files exist
now := time.Now()
err = generateStamp.Ensure(now)
Ck(err)
err = commitStamp.Ensure(now)
Ck(err)

// Check if the file exists
_, err = os.Stat(path)
_, err = os.Stat(promptFn)
if os.IsNotExist(err) {
err = createPromptFile(path)
err = createPromptFile(promptFn)
Ck(err)
} else {
Ck(err)
Expand Down Expand Up @@ -648,15 +620,19 @@ func runTest(fn string) (err error) {
return err
}

func generate(g *core.Grokker, p *Prompt, testResults string) (err error) {
func generate(g *core.Grokker, p *Prompt) (err error) {
defer Return(&err)

prompt := p.Txt
Pl(prompt)

testResults, err := getTestResults(testFn, p.In, p.Out)
Ck(err)
if len(testResults) > 0 {
Pl("Including test results in prompt")
prompt = Spf("%s\n\n%s", p.Txt, testResults)
}

inFns := p.In
outFns := p.Out
var outFls []core.FileLang
Expand All @@ -671,7 +647,7 @@ func generate(g *core.Grokker, p *Prompt, testResults string) (err error) {

sysmsg := p.Sysmsg
if sysmsg == "" {
Pf("Sysmsg header missing, using default.")
Pl("Sysmsg header missing, using default.")
sysmsg = DefaultSysmsg
}
Pf("Sysmsg: %s\n", sysmsg)
Expand Down Expand Up @@ -915,12 +891,47 @@ func menu(g *core.Grokker) (action string, err error) {
return "auto", nil
case "x":
Pl("Operation aborted by user.")
return "", fmt.Errorf("operation aborted")
return "", nil
default:
fmt.Printf("\nUnknown option: %s\n\n", string(char))
// Continue the loop to re-display the menu
}
}
}

// getTestResults reads the test file and returns its contents if it
// exists and is newer than all input and output files. If there are
// no new test results, then the test file is cleared and an empty
// string is returned.
func getTestResults(testFn string, inFns []string, outFns []string) (testResults string, err error) {
// get the test file's modification time
testStat, err := os.Stat(testFn)
if os.IsNotExist(err) {
err = nil
} else {
Ck(err)
// Check if the test file is newer than any input or output files
fns := append(inFns, outFns...)
for _, fn := range fns {
inStat, err := os.Stat(fn)
Ck(err)
if testStat.ModTime().After(inStat.ModTime()) {
// return the test file contents
buf, err := os.ReadFile(testFn)
Ck(err)
testResults = string(buf)
break
}
}
}
if len(testResults) == 0 {
// Clear the test file
Pl("Clearing test file")
err = os.WriteFile(testFn, []byte{}, 0644)
Ck(err)
}

return testResults, err
}
```
EOF_/home/stevegt/lab/grokker/v3/aidda/aidda.go
17 changes: 10 additions & 7 deletions v3/aidda/aidda.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ func Do(g *core.Grokker, args ...string) (err error) {
case "abort":
// Abort the current operation
Pl("Operation aborted by user.")
return fmt.Errorf("operation aborted")
return nil
default:
PrintUsageAndExit()
}
Expand All @@ -264,9 +264,9 @@ func PrintUsageAndExit() {
fmt.Println(" generate - Generate changes from GPT based on the prompt")
fmt.Println(" regenerate - Regenerate code from the prompt without committing")
fmt.Println(" force-commit - Commit changes without checking if the prompt has been updated")
fmt.Println(" test - Run tests and include the results in the prompt file")
fmt.Println(" test - Run tests and include the results in the next LLM prompt")
fmt.Println(" auto - Automatically run generate or commit based on file timestamps")
fmt.Println(" abort - Abort the current operation")
fmt.Println(" abort - Abort subcommand processing")
os.Exit(1)
}

Expand Down Expand Up @@ -856,9 +856,9 @@ func menu(g *core.Grokker) (action string, err error) {
fmt.Println(" [r]egenerate - Regenerate code from the prompt without committing")
fmt.Println(" [c]ommit - Commit using the current prompt file contents as the commit message")
fmt.Println(" [f]orce-commit - Commit changes without checking if the prompt has been updated")
fmt.Println(" [t]est - Run tests and include the results in the prompt file")
fmt.Println(" [t]est - Run tests and include the results in the next LLM prompt")
fmt.Println(" [a]uto - Automatically run generate or commit based on file timestamps")
fmt.Println(" e[x]it - Abort and exit the menu")
fmt.Println(" e[x]it - Abort and exit the menu")
fmt.Println("Press the corresponding key to select an action...")

// Initialize keyboard
Expand Down Expand Up @@ -888,8 +888,7 @@ func menu(g *core.Grokker) (action string, err error) {
case "a":
return "auto", nil
case "x":
Pl("Operation aborted by user.")
return "", fmt.Errorf("operation aborted")
return "abort", nil
default:
fmt.Printf("\nUnknown option: %s\n\n", string(char))
// Continue the loop to re-display the menu
Expand All @@ -912,6 +911,10 @@ func getTestResults(testFn string, inFns []string, outFns []string) (testResults
fns := append(inFns, outFns...)
for _, fn := range fns {
inStat, err := os.Stat(fn)
// skip if the file does not exist
if os.IsNotExist(err) {
continue
}
Ck(err)
if testStat.ModTime().After(inStat.ModTime()) {
// return the test file contents
Expand Down

0 comments on commit 781dd22

Please sign in to comment.