|
1 | 1 | package parser |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "bufio" |
5 | | - "bytes" |
6 | 4 | "fmt" |
7 | 5 | "os" |
8 | | - "path/filepath" |
9 | 6 | "strings" |
10 | 7 |
|
11 | 8 | "github.com/githubnext/gh-aw/pkg/logger" |
@@ -452,171 +449,3 @@ func processImportsFromFrontmatterWithManifestAndSource(frontmatter map[string]a |
452 | 449 | ImportInputs: importInputs, |
453 | 450 | }, nil |
454 | 451 | } |
455 | | - |
456 | | -// ExpandIncludes recursively expands @include and @import directives until no more remain |
457 | | -// This matches the bash expand_includes function behavior |
458 | | -func ExpandIncludes(content, baseDir string, extractTools bool) (string, error) { |
459 | | - expandedContent, _, err := ExpandIncludesWithManifest(content, baseDir, extractTools) |
460 | | - return expandedContent, err |
461 | | -} |
462 | | - |
463 | | -// ExpandIncludesWithManifest recursively expands @include and @import directives and returns list of included files |
464 | | -func ExpandIncludesWithManifest(content, baseDir string, extractTools bool) (string, []string, error) { |
465 | | - const maxDepth = 10 |
466 | | - currentContent := content |
467 | | - visited := make(map[string]bool) |
468 | | - |
469 | | - for depth := 0; depth < maxDepth; depth++ { |
470 | | - // Process includes in current content |
471 | | - processedContent, err := processIncludesWithVisited(currentContent, baseDir, extractTools, visited) |
472 | | - if err != nil { |
473 | | - return "", nil, err |
474 | | - } |
475 | | - |
476 | | - // For tools mode, check if we still have @include or @import directives |
477 | | - if extractTools { |
478 | | - if !strings.Contains(processedContent, "@include") && !strings.Contains(processedContent, "@import") { |
479 | | - // No more includes to process for tools mode |
480 | | - currentContent = processedContent |
481 | | - break |
482 | | - } |
483 | | - } else { |
484 | | - // For content mode, check if content changed |
485 | | - if processedContent == currentContent { |
486 | | - // No more includes to process |
487 | | - break |
488 | | - } |
489 | | - } |
490 | | - |
491 | | - currentContent = processedContent |
492 | | - } |
493 | | - |
494 | | - // Convert visited map to slice of file paths (make them relative to baseDir if possible) |
495 | | - var includedFiles []string |
496 | | - for filePath := range visited { |
497 | | - // Try to make path relative to baseDir for cleaner output |
498 | | - relPath, err := filepath.Rel(baseDir, filePath) |
499 | | - if err == nil && !strings.HasPrefix(relPath, "..") { |
500 | | - includedFiles = append(includedFiles, relPath) |
501 | | - } else { |
502 | | - includedFiles = append(includedFiles, filePath) |
503 | | - } |
504 | | - } |
505 | | - |
506 | | - if extractTools { |
507 | | - // For tools mode, merge all extracted JSON objects |
508 | | - mergedTools, err := mergeToolsFromJSON(currentContent) |
509 | | - return mergedTools, includedFiles, err |
510 | | - } |
511 | | - |
512 | | - return currentContent, includedFiles, nil |
513 | | -} |
514 | | - |
515 | | -// ExpandIncludesForEngines recursively expands @include and @import directives to extract engine configurations |
516 | | -func ExpandIncludesForEngines(content, baseDir string) ([]string, error) { |
517 | | - return expandIncludesForField(content, baseDir, extractEngineFromContent, "") |
518 | | -} |
519 | | - |
520 | | -// ExpandIncludesForSafeOutputs recursively expands @include and @import directives to extract safe-outputs configurations |
521 | | -func ExpandIncludesForSafeOutputs(content, baseDir string) ([]string, error) { |
522 | | - return expandIncludesForField(content, baseDir, extractSafeOutputsFromContent, "{}") |
523 | | -} |
524 | | - |
525 | | -// expandIncludesForField recursively expands includes to extract a specific frontmatter field |
526 | | -func expandIncludesForField(content, baseDir string, extractFunc func(string) (string, error), emptyValue string) ([]string, error) { |
527 | | - const maxDepth = 10 |
528 | | - var results []string |
529 | | - currentContent := content |
530 | | - |
531 | | - for depth := 0; depth < maxDepth; depth++ { |
532 | | - // Process includes in current content to extract the field |
533 | | - processedResults, processedContent, err := processIncludesForField(currentContent, baseDir, extractFunc, emptyValue) |
534 | | - if err != nil { |
535 | | - return nil, err |
536 | | - } |
537 | | - |
538 | | - // Add found results to the list |
539 | | - results = append(results, processedResults...) |
540 | | - |
541 | | - // Check if content changed |
542 | | - if processedContent == currentContent { |
543 | | - // No more includes to process |
544 | | - break |
545 | | - } |
546 | | - |
547 | | - currentContent = processedContent |
548 | | - } |
549 | | - |
550 | | - return results, nil |
551 | | -} |
552 | | - |
553 | | -// ProcessIncludesForEngines processes import directives to extract engine configurations |
554 | | -func ProcessIncludesForEngines(content, baseDir string) ([]string, string, error) { |
555 | | - return processIncludesForField(content, baseDir, extractEngineFromContent, "") |
556 | | -} |
557 | | - |
558 | | -// ProcessIncludesForSafeOutputs processes import directives to extract safe-outputs configurations |
559 | | -func ProcessIncludesForSafeOutputs(content, baseDir string) ([]string, string, error) { |
560 | | - return processIncludesForField(content, baseDir, extractSafeOutputsFromContent, "{}") |
561 | | -} |
562 | | - |
563 | | -// processIncludesForField processes import directives to extract a specific frontmatter field |
564 | | -func processIncludesForField(content, baseDir string, extractFunc func(string) (string, error), emptyValue string) ([]string, string, error) { |
565 | | - scanner := bufio.NewScanner(strings.NewReader(content)) |
566 | | - var result bytes.Buffer |
567 | | - var results []string |
568 | | - |
569 | | - for scanner.Scan() { |
570 | | - line := scanner.Text() |
571 | | - |
572 | | - // Parse import directive |
573 | | - directive := ParseImportDirective(line) |
574 | | - if directive != nil { |
575 | | - isOptional := directive.IsOptional |
576 | | - includePath := directive.Path |
577 | | - |
578 | | - // Handle section references (file.md#Section) - for frontmatter fields, we ignore sections |
579 | | - var filePath string |
580 | | - if strings.Contains(includePath, "#") { |
581 | | - parts := strings.SplitN(includePath, "#", 2) |
582 | | - filePath = parts[0] |
583 | | - // Note: section references are ignored for frontmatter field extraction |
584 | | - } else { |
585 | | - filePath = includePath |
586 | | - } |
587 | | - |
588 | | - // Resolve file path |
589 | | - fullPath, err := ResolveIncludePath(filePath, baseDir, nil) |
590 | | - if err != nil { |
591 | | - if isOptional { |
592 | | - // For optional includes, skip extraction |
593 | | - continue |
594 | | - } |
595 | | - // For required includes, fail compilation with an error |
596 | | - return nil, "", fmt.Errorf("failed to resolve required include '%s': %w", filePath, err) |
597 | | - } |
598 | | - |
599 | | - // Read the included file |
600 | | - fileContent, err := os.ReadFile(fullPath) |
601 | | - if err != nil { |
602 | | - // For any processing errors, fail compilation |
603 | | - return nil, "", fmt.Errorf("failed to read included file '%s': %w", fullPath, err) |
604 | | - } |
605 | | - |
606 | | - // Extract the field using the provided extraction function |
607 | | - fieldJSON, err := extractFunc(string(fileContent)) |
608 | | - if err != nil { |
609 | | - return nil, "", fmt.Errorf("failed to extract field from '%s': %w", fullPath, err) |
610 | | - } |
611 | | - |
612 | | - if fieldJSON != "" && fieldJSON != emptyValue { |
613 | | - results = append(results, fieldJSON) |
614 | | - } |
615 | | - } else { |
616 | | - // Regular line, just pass through |
617 | | - result.WriteString(line + "\n") |
618 | | - } |
619 | | - } |
620 | | - |
621 | | - return results, result.String(), nil |
622 | | -} |
0 commit comments