diff --git a/pkg/tools/execute/execute_test.go b/pkg/tools/execute/execute_test.go index e8ed5be..7654032 100644 --- a/pkg/tools/execute/execute_test.go +++ b/pkg/tools/execute/execute_test.go @@ -962,6 +962,10 @@ func TestDetectParallelClass(t *testing.T) { {"#!/bin/sh\n# ollie:parallel write extra\n", lockClassWrite}, {"#!/bin/sh\nno annotation\n", lockClassGlobal}, {"", lockClassGlobal}, + // lua-style comment + {"#!/usr/bin/env lua\n-- ollie:parallel read\n", lockClassRead}, + // C-style comment + {"// ollie:parallel read\n", lockClassRead}, // annotation after line 10 is ignored {strings.Repeat("# filler\n", 10) + "# ollie:parallel read\n", lockClassGlobal}, } diff --git a/pkg/tools/execute/flock.go b/pkg/tools/execute/flock.go index 4391803..09f091d 100644 --- a/pkg/tools/execute/flock.go +++ b/pkg/tools/execute/flock.go @@ -33,10 +33,9 @@ func classifyStep(step CodeStep) lockClass { } // detectParallelClass scans the first 10 lines of a tool script for an -// ollie:parallel annotation: -// -// # ollie:parallel read → lockClassRead (safe to run concurrently with other reads) -// # ollie:parallel write → lockClassWrite (needs exclusive access to the file it writes) +// ollie:parallel annotation. The annotation is comment-syntax-agnostic: +// it matches "ollie:parallel read" or "ollie:parallel write" anywhere in +// the line, so it works with # (bash/python), -- (lua), // (go), etc. // // Absence of the annotation → lockClassGlobal (serialize). func detectParallelClass(code string) lockClass { @@ -45,11 +44,11 @@ func detectParallelClass(code string) lockClass { lines = lines[:10] } for _, line := range lines { - line = strings.TrimSpace(line) - if !strings.HasPrefix(line, "# ollie:parallel") { + idx := strings.Index(line, "ollie:parallel") + if idx < 0 { continue } - rest := strings.TrimSpace(strings.TrimPrefix(line, "# ollie:parallel")) + rest := strings.TrimSpace(line[idx+len("ollie:parallel"):]) switch { case rest == "read" || strings.HasPrefix(rest, "read "): return lockClassRead @@ -88,7 +87,7 @@ func acquireFlock(dir, name string, exclusive bool) (*os.File, error) { } // IsParallelRead implements tools.ParallelClassifier. Returns true when the -// named tool script carries a "# ollie:parallel read" annotation. +// named tool script carries an "ollie:parallel read" annotation. func (e *Server) IsParallelRead(name string) bool { code, err := ReadTool(name) if err != nil {