Created
December 13, 2023 16:45
-
-
Save lsongdev/e7d0407ca05c7b621401ad7ded3182ae to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"fmt" | |
"io" | |
"log" | |
"os" | |
"strings" | |
) | |
// Items is an interface that represents either a Block or a Directive. | |
type Items interface { | |
isItem() bool | |
Type() string | |
} | |
// Block represents a block in the Nginx configuration. | |
type Block struct { | |
Name string | |
Items []Items | |
} | |
func (b Block) isItem() bool { | |
return true | |
} | |
func (b Block) Type() string { | |
return "block" | |
} | |
// Directive represents a directive in the Nginx configuration. | |
type Directive struct { | |
Name string | |
Value string | |
} | |
func (d Directive) isItem() bool { | |
return true | |
} | |
func (d Directive) Type() string { | |
return "directive" | |
} | |
func parseNginxConfig(reader io.Reader) (stack []Items) { | |
scanner := bufio.NewScanner(reader) | |
var currentBlock *Block | |
var stackPointer []Items | |
for scanner.Scan() { | |
line := strings.TrimSpace(scanner.Text()) | |
if len(line) == 0 || line[0] == '#' { | |
continue | |
} | |
if strings.HasSuffix(line, "{") { | |
blockName := strings.TrimSuffix(line, "{") | |
newBlock := &Block{Name: blockName} | |
if currentBlock != nil { | |
currentBlock.Items = append(currentBlock.Items, newBlock) | |
} else { | |
stack = append(stack, newBlock) | |
} | |
stackPointer = append(stackPointer, newBlock) | |
currentBlock = newBlock | |
} else if strings.HasPrefix(line, "}") { | |
if len(stackPointer) > 1 { | |
stackPointer = stackPointer[:len(stackPointer)-1] | |
currentBlock = stackPointer[len(stackPointer)-1].(*Block) | |
} else { | |
currentBlock = nil | |
} | |
} else { | |
parts := strings.SplitN(line, " ", 2) | |
if len(parts) == 2 { | |
name := strings.TrimSpace(parts[0]) | |
value := strings.TrimSpace(parts[1]) | |
directive := &Directive{Name: name, Value: value} | |
if currentBlock != nil { | |
currentBlock.Items = append(currentBlock.Items, directive) | |
} else { | |
stack = append(stack, directive) | |
} | |
} | |
} | |
} | |
if err := scanner.Err(); err != nil { | |
fmt.Println("Error reading file:", err) | |
return nil | |
} | |
return stack | |
} | |
func main() { | |
// Replace this with your actual file path | |
filePath := "/Users/Lsong/Projects/confbook/nginx/sites-available/awtrix.conf" | |
file, err := os.Open(filePath) | |
if err != nil { | |
fmt.Println("Error opening file:", err) | |
return | |
} | |
defer file.Close() | |
nginxConfig := parseNginxConfig(file) | |
printNginxConfig(nginxConfig) | |
} | |
func printNginxConfig(items []Items) { | |
for _, item := range items { | |
switch v := item.(type) { | |
case *Block: | |
printBlock(v) | |
case *Directive: | |
printDirective(v) | |
} | |
} | |
} | |
func printBlock(block *Block) { | |
log.Println(block.Name) | |
printNginxConfig(block.Items) | |
} | |
func printDirective(directive *Directive) { | |
log.Println(directive.Name, directive.Value) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment