Skip to content

Commit 9688273

Browse files
authored
Refactor/organize wails services (#19)
* refactor: Move Wails service bindings to internal/wails package Moves all Wails service wrapper files from root directory to internal/wails/ for better organization and separation of concerns. Changes: - Moved: jwt_service.go, barcode_service.go, conversion_service.go, data_generator_service.go, codeformatter_service.go - Updated package from 'main' to 'wails' - Changed startup() to Startup() (exported method) - Updated main.go and server.go imports - Updated type references to use wails package * fix: wrong be package, try to build proper binary for each platform * fix: unit tests * fix: unit tests path
1 parent ff73051 commit 9688273

22 files changed

Lines changed: 887 additions & 137 deletions

.github/workflows/build.yml

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,43 @@ jobs:
6767
fi
6868
shell: bash
6969

70-
# Upload build artifacts
70+
# Package and upload build artifacts
71+
- name: Package Artifacts
72+
run: |
73+
mkdir -p release
74+
if [ "${{ matrix.os }}" = "macos-latest" ]; then
75+
# macOS: create DMG using create-dmg
76+
brew install create-dmg
77+
create-dmg \
78+
--volname "Dev-Toolbox" \
79+
--window-pos 200 120 \
80+
--window-size 800 400 \
81+
--icon-size 100 \
82+
--app-drop-link 600 185 \
83+
"release/dev-toolbox-${{ matrix.build }}.dmg" \
84+
"build/bin/dev-toolbox.app"
85+
elif [ "${{ matrix.os }}" = "windows-latest" ]; then
86+
# Windows: rename binary with .exe extension
87+
mv build/bin/dev-toolbox build/bin/dev-toolbox.exe
88+
cp build/bin/dev-toolbox.exe release/dev-toolbox-${{ matrix.build }}.exe
89+
else
90+
# Linux: create AppImage or tar.gz
91+
tar -czf "release/dev-toolbox-${{ matrix.build }}.tar.gz" -C build/bin dev-toolbox
92+
fi
93+
shell: bash
94+
7195
- name: Upload Artifacts
7296
uses: actions/upload-artifact@v4
7397
with:
74-
name: Wails-Build-${{ matrix.os }}-${{ github.ref_name }}
75-
path: build/bin/*
98+
name: dev-toolbox-${{ matrix.build }}-${{ github.ref_name }}
99+
path: release/*
76100

77101
# Create Release and upload assets (only on tags)
78102
- name: Create Release
79103
if: startsWith(github.ref, 'refs/tags/v')
80104
uses: softprops/action-gh-release@v1
81105
with:
82-
files: build/bin/*
106+
files: release/*
83107
draft: false
84108
prerelease: false
85109
generate_release_notes: true

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ jobs:
5151
run: go mod download
5252

5353
- name: Run Go Tests
54-
run: go test ./internal/converter/... -v -race
54+
run: go test ./internal/... -v -race
5555

5656
- name: Run Tests with Coverage
57-
run: go test ./internal/converter/... -coverprofile=coverage.out
57+
run: go test ./internal/... -coverprofile=coverage.out
5858

5959
- name: Generate Coverage Report
6060
run: |

internal/codeformatter/service.go

Lines changed: 103 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -269,55 +269,124 @@ func extractXMLAttributes(xmlStr, elementName, attrName string) (string, error)
269269

270270
// formatXMLPretty formats XML with indentation
271271
func formatXMLPretty(xmlStr string) (string, error) {
272-
var buf bytes.Buffer
273-
encoder := json.NewEncoder(&buf)
274-
encoder.SetIndent("", " ")
272+
// Use a simple but robust approach: tokenize and rebuild
273+
type token struct {
274+
typ string // "decl", "open", "close", "selfclose", "text", "comment"
275+
value string
276+
name string // for tags
277+
}
278+
279+
var tokens []token
280+
i := 0
281+
for i < len(xmlStr) {
282+
if xmlStr[i] == '<' {
283+
// Find end of tag
284+
end := i + 1
285+
for end < len(xmlStr) && xmlStr[end] != '>' {
286+
end++
287+
}
288+
if end >= len(xmlStr) {
289+
break
290+
}
291+
tagContent := xmlStr[i+1 : end]
292+
fullTag := xmlStr[i : end+1]
293+
294+
if strings.HasPrefix(tagContent, "?") {
295+
tokens = append(tokens, token{typ: "decl", value: fullTag})
296+
} else if strings.HasPrefix(tagContent, "!--") {
297+
tokens = append(tokens, token{typ: "comment", value: fullTag})
298+
} else if strings.HasPrefix(tagContent, "/") {
299+
name := strings.TrimSpace(tagContent[1:])
300+
tokens = append(tokens, token{typ: "close", value: fullTag, name: name})
301+
} else if strings.HasSuffix(tagContent, "/") {
302+
name := strings.TrimSpace(strings.TrimSuffix(tagContent, "/"))
303+
if idx := strings.IndexAny(name, " \t"); idx != -1 {
304+
name = name[:idx]
305+
}
306+
tokens = append(tokens, token{typ: "selfclose", value: fullTag, name: name})
307+
} else {
308+
name := strings.TrimSpace(tagContent)
309+
if idx := strings.IndexAny(name, " \t"); idx != -1 {
310+
name = name[:idx]
311+
}
312+
tokens = append(tokens, token{typ: "open", value: fullTag, name: name})
313+
}
314+
i = end + 1
315+
} else {
316+
// Text content
317+
start := i
318+
for i < len(xmlStr) && xmlStr[i] != '<' {
319+
i++
320+
}
321+
text := strings.TrimSpace(xmlStr[start:i])
322+
if text != "" {
323+
tokens = append(tokens, token{typ: "text", value: text})
324+
}
325+
}
326+
}
275327

276-
// Simple pretty printing - parse and re-serialize
277-
// In production, use proper XML indentation
328+
// Rebuild with proper indentation
278329
var result strings.Builder
279330
indent := 0
280-
inTag := false
331+
for j, tok := range tokens {
332+
switch tok.typ {
333+
case "decl":
334+
result.WriteString(tok.value)
335+
result.WriteByte('\n')
336+
case "comment":
337+
result.WriteString(strings.Repeat(" ", indent))
338+
result.WriteString(tok.value)
339+
result.WriteByte('\n')
340+
case "open":
341+
// Check if this is an inline element (text follows and then close)
342+
isInline := false
343+
if j+2 < len(tokens) && tokens[j+1].typ == "text" && tokens[j+2].typ == "close" && tokens[j+2].name == tok.name {
344+
isInline = true
345+
}
281346

282-
for i := 0; i < len(xmlStr); i++ {
283-
ch := xmlStr[i]
347+
if !isInline && result.Len() > 0 && !strings.HasSuffix(result.String(), "\n") {
348+
result.WriteByte('\n')
349+
}
350+
if !isInline {
351+
result.WriteString(strings.Repeat(" ", indent))
352+
}
353+
result.WriteString(tok.value)
354+
if !isInline {
355+
indent++
356+
}
357+
case "close":
358+
// Check if previous was inline (open + text + close sequence)
359+
wasInline := j >= 2 && tokens[j-2].typ == "open" && tokens[j-2].name == tok.name && tokens[j-1].typ == "text"
284360

285-
switch ch {
286-
case '<':
287-
if i+1 < len(xmlStr) && xmlStr[i+1] == '/' {
288-
// Closing tag
361+
if !wasInline {
289362
indent--
290-
if result.Len() > 0 && result.String()[result.Len()-1] == '\n' {
291-
result.WriteString(strings.Repeat(" ", indent))
363+
if indent < 0 {
364+
indent = 0
365+
}
366+
if result.Len() > 0 && !strings.HasSuffix(result.String(), "\n") {
367+
result.WriteByte('\n')
292368
}
369+
result.WriteString(strings.Repeat(" ", indent))
293370
}
294-
result.WriteByte(ch)
295-
inTag = true
296-
case '>':
297-
result.WriteByte(ch)
298-
inTag = false
299-
if i+1 < len(xmlStr) && xmlStr[i+1] != '<' && xmlStr[i+1] != ' ' && xmlStr[i+1] != '\t' && xmlStr[i+1] != '\n' {
300-
// Content follows
301-
} else if i+1 < len(xmlStr) && xmlStr[i+1] == '<' && xmlStr[i+2] != '/' {
302-
// Opening tag follows
303-
indent++
371+
result.WriteString(tok.value)
372+
if j < len(tokens)-1 {
304373
result.WriteByte('\n')
305-
result.WriteString(strings.Repeat(" ", indent))
306-
} else if i+1 < len(xmlStr) && xmlStr[i+1] == '<' && xmlStr[i+2] == '/' {
307-
// Closing tag follows
374+
}
375+
case "selfclose":
376+
if result.Len() > 0 && !strings.HasSuffix(result.String(), "\n") {
308377
result.WriteByte('\n')
309-
result.WriteString(strings.Repeat(" ", indent))
310378
}
311-
case '\n', '\t':
312-
if !inTag {
313-
// Skip whitespace outside tags
379+
result.WriteString(strings.Repeat(" ", indent))
380+
result.WriteString(tok.value)
381+
if j < len(tokens)-1 {
382+
result.WriteByte('\n')
314383
}
315-
default:
316-
result.WriteByte(ch)
384+
case "text":
385+
result.WriteString(tok.value)
317386
}
318387
}
319388

320-
return result.String(), nil
389+
return strings.TrimSpace(result.String()), nil
321390
}
322391

323392
// minifyXML removes whitespace from XML

0 commit comments

Comments
 (0)