2222#
2323# 2. Full Regression Mode: If no arguments are provided, it runs a predefined
2424# list of all Go snippets in the repository. This is used for scheduled weekly tests.
25- # Example: ./tools/go-snippets/runner.sh run
25+ # Example: ./tools/go-snippets/runner.sh build
2626
2727# --- Configuration ---
28+ # Define color codes for colored output.
2829RED=' \033[0;31m'
2930GREEN=' \033[0;32m'
3031NC=' \033[0m' # No Color
32+
33+ # Global exit code for the script. It is set to 1 if any test fails.
3134EXIT_CODE=0
35+
36+ # The configuration file that lists all Go snippets to be tested.
3237SNIPPETS_FILE=" tools/go-snippets/files_to_test.txt"
3338
34- # --- Helper Function ---
35- # execute_and_check executes a command, captures the output,
36- # and prints a formatted, colored status message.
39+ # --- Helper Functions ---
40+
41+ # should_process_line determines if a line from the snippets file should be processed.
42+ # It returns 0 (success) for valid lines and 1 (failure) for comments or empty lines.
43+ #
44+ # @param {string} line - The line to check.
45+ # @returns {int} 0 if the line should be processed, 1 otherwise.
46+ should_process_line () {
47+ local line=$1
48+ # Remove all whitespace from the line to correctly handle lines with only spaces or tabs.
49+ local trimmed_line=$( echo " ${line} " | tr -d ' [:space:]' )
50+ # Return failure (1) if the trimmed line is empty or starts with a hash.
51+ if [[ -z " ${trimmed_line} " || " ${trimmed_line} " =~ ^# ]]; then
52+ return 1
53+ else
54+ return 0
55+ fi
56+ }
57+
58+ # find_snippet_line searches the SNIPPETS_FILE for a given Go file path.
59+ # It ignores comments and returns the full line from the file.
60+ #
61+ # @param {string} file_path_from_root - The full path to the Go file relative to the project root (e.g., "examples/go/snippets/quickstart/main.go").
62+ # @returns {string} The matching line from SNIPPETS_FILE, or an empty string if not found.
63+ find_snippet_line () {
64+ local file_path_from_root=$1
65+ # The SNIPPETS_FILE contains paths relative to 'examples/go/', so we strip that prefix from the input path.
66+ local relative_path=${file_path_from_root# examples/ go/ }
67+ # First, filter out all commented lines, then search for the relative path.
68+ grep -v ' ^\s*#' " ${SNIPPETS_FILE} " | grep " ${relative_path} "
69+ }
70+
71+ # get_command_for_action constructs the appropriate Go command based on the action.
72+ # It specifically handles stripping arguments for the 'build' action.
73+ #
74+ # @param {string} action - The action to perform ("build" or "run").
75+ # @param {string} line - The line from the snippets file, which may include arguments.
76+ # @returns {string} The fully formed Go command.
77+ get_command_for_action () {
78+ local action=$1
79+ local line=$2
80+ local command=" "
81+
82+ if [ " ${action} " == " build" ]; then
83+ # For 'build', extract only the file paths, ignoring any arguments.
84+ # 'go build' does not accept application arguments, so they must be stripped.
85+ local files_to_build=$( echo " ${line} " | awk ' {for(i=1;i<=NF;i++) if($i ~ /\.go$/) printf "%s ", $i}' )
86+ command=" go build ${files_to_build} "
87+ elif [ " ${action} " == " run" ]; then
88+ # For 'run', use the line as is, as 'go run' will pass arguments to the application.
89+ command=" go run ${line} "
90+ fi
91+ echo " ${command} "
92+ }
93+
94+ # execute_and_check executes a command and prints a formatted status message.
3795#
3896# @param {string} command - The full command to execute.
3997# @param {string} display_name - A user-friendly name for the command/file.
4098execute_and_check () {
4199 local command=$1
42100 local display_name=$2
43101
44- # Capture the run output and exit code .
102+ # 'eval' is used to correctly execute the command string, which may contain quotes and other special characters .
45103 local output
46104 output=$( eval ${command} 2>&1 )
47105 local exit_code=$?
48106
49107 if [ ${exit_code} -eq 0 ]; then
50- # Print PASS status in green if run is successful.
51108 echo -e " [${GREEN} PASS${NC} ] ${display_name} "
52109 else
53- # Print FAIL status in red and the indented error message.
54110 echo -e " [${RED} FAIL${NC} ] ${display_name} "
111+ # Indent the error output for better readability.
55112 echo " ${output} " | sed ' s/^/ /'
56- # Set the script's exit code to 1 to fail the CI check .
113+ # Set the global exit code to indicate failure .
57114 EXIT_CODE=1
58115 fi
59116}
60117
61118# --- Main Logic ---
62119
63- if [[ " $1 " != " build" && " $1 " != " run" ]]; then
64- echo " Usage: $0 <build|run> [file1 file2 ...]"
65- exit 1
66- fi
120+ # This check prevents the main logic from running if the script is being sourced (e.g., by the test script).
121+ if [[ " ${BASH_SOURCE[0]} " == " ${0} " ]]; then
122+ # Validate the first argument is either 'build' or 'run'.
123+ if [[ " $1 " != " build" && " $1 " != " run" ]]; then
124+ echo " Usage: $0 <build|run> [file1 file2 ...]"
125+ exit 1
126+ fi
67127
68- ACTION=$1
69- shift
128+ ACTION=$1
129+ shift # Remove the first argument, so '$@' contains only the file paths.
70130
71- # Run go mod tidy once for the entire examples/go module
72- (cd examples/go && go mod tidy)
73- if [ $? -ne 0 ]; then
74- echo -e " [${RED} FAIL${NC} ] go mod tidy failed in examples/go"
75- EXIT_CODE=1
76- fi
131+ # Ensure all Go module dependencies are tidy before running any builds or tests.
132+ # This is run from the 'examples/go' directory where the go.mod file is located.
133+ (cd examples/go && go mod tidy)
134+ if [ $? -ne 0 ]; then
135+ echo -e " [${RED} FAIL${NC} ] go mod tidy failed in examples/go"
136+ exit 1 # Exit immediately if dependencies are not clean.
137+ fi
138+
139+ # Check if file paths were provided as arguments (Targeted Mode).
140+ if [ " $# " -gt 0 ]; then
141+ echo " Running targeted Go snippet ${ACTION} for changed files..."
142+ echo
143+ for file in " $@ " ; do
144+ # Find the corresponding line in the snippets file for the changed file.
145+ line=$( find_snippet_line " ${file} " )
146+ if [[ -z " ${line} " ]]; then
147+ echo -e " [${RED} FAIL${NC} ] ${file} "
148+ echo " Error: No corresponding entry found in ${SNIPPETS_FILE} ."
149+ EXIT_CODE=1
150+ continue # Skip to the next file.
151+ fi
152+
153+ # Construct the appropriate build or run command.
154+ command_to_execute=$( get_command_for_action " ${ACTION} " " ${line} " )
155+ if [[ -n " ${command_to_execute} " ]]; then
156+ # Execute the command from the 'examples/go' directory.
157+ execute_and_check " (cd examples/go && ${command_to_execute} )" " ${file} "
158+ fi
159+ done
160+ else
161+ # If no file paths were provided, run in Full Regression Mode.
162+ echo " Running full Go snippet ${ACTION} ..."
163+ echo
164+ # Read the snippets file line by line.
165+ while IFS= read -r line; do
166+ # Skip empty lines and comments.
167+ if ! should_process_line " ${line} " ; then
168+ continue
169+ fi
170+
171+ command_to_execute=$( get_command_for_action " ${ACTION} " " ${line} " )
172+ if [[ -n " ${command_to_execute} " ]]; then
173+ execute_and_check " (cd examples/go && ${command_to_execute} )" " ${line} "
174+ fi
175+ done < " ${SNIPPETS_FILE} "
176+ fi
77177
78- if [ " $# " -gt 0 ]; then
79- echo " Running targeted Go snippet ${ACTION} for changed files..."
80- echo
81- for file in " $@ " ; do
82- # Find the line in snippets.txt that contains the changed file
83- line=$( grep " ${file# examples/ go/ } " ${SNIPPETS_FILE} )
84- if [ " ${ACTION} " == " build" ]; then
85- command_to_execute=" go build ${line} "
86- elif [ " ${ACTION} " == " run" ]; then
87- command_to_execute=" go run ${line} "
88- fi
89-
90- if [[ -n " ${command_to_execute} " ]]; then
91- execute_and_check " (cd examples/go && ${command_to_execute} )" " ${file} "
92- fi
93- done
94- else
95- echo " Running full Go snippet ${ACTION} ..."
96178 echo
97- while IFS= read -r line; do
98- command_to_execute=" "
99- if [ " ${ACTION} " == " build" ]; then
100- command_to_execute=" go build ${line} "
101- elif [ " ${ACTION} " == " run" ]; then
102- command_to_execute=" go run ${line} "
103- fi
104-
105- if [[ -n " ${command_to_execute} " ]]; then
106- execute_and_check " (cd examples/go && ${command_to_execute} )" " ${line} "
107- fi
108- done < " ${SNIPPETS_FILE} "
179+ echo " Script finished."
180+ # Exit with the final status code (0 for success, 1 for failure).
181+ exit ${EXIT_CODE}
109182fi
110-
111- echo
112- echo " Script finished."
113- exit ${EXIT_CODE}
0 commit comments