Skip to content

Commit 0a9ef13

Browse files
committed
chore: address coderabbitai feedback
1 parent 73d67fa commit 0a9ef13

2 files changed

Lines changed: 77 additions & 1 deletion

File tree

docs/serena-mcp.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ This keeps the Go version aligned with the project's build image and avoids host
5757

5858
### Target Serena Version
5959

60-
As of 2026-06-02, the patch targets the Serena image with:
60+
As of 2026-06-15, the patch targets the Serena image with:
6161

6262
- Base image: `ghcr.io/oraios/serena:latest`
6363
- Image version label: `main`

main.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ var (
5050
// osLink is a package-level alias for os.Link to allow tests to inject failures.
5151
var osLink = os.Link
5252

53+
// rootCmd is the top-level Cobra command that defines the CLI interface.
5354
var rootCmd = &cobra.Command{
5455
Use: "lilt <source_directory>",
5556
Short: "Convert Hi-Res FLAC/ALAC files to 16-bit FLAC files",
@@ -74,6 +75,7 @@ Licensed under MIT License`,
7475
Version: version,
7576
}
7677

78+
// init registers all command-line flags and sets default configuration values.
7779
func init() {
7880
rootCmd.Flags().StringVar(&config.TargetDir, "target-dir", "./transcoded", "Specify target directory")
7981
rootCmd.Flags().BoolVar(&config.CopyImages, "copy-images", false, "Copy JPG and PNG files")
@@ -88,13 +90,17 @@ func init() {
8890
config.SoxCommand = "sox"
8991
}
9092

93+
// main is the program entry point. It executes the root Cobra command and
94+
// exits with a non-zero code on error.
9195
func main() {
9296
if err := rootCmd.Execute(); err != nil {
9397
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
9498
os.Exit(1)
9599
}
96100
}
97101

102+
// runConverter is the main command handler. It validates arguments, sets up
103+
// the SoX command, processes audio files, and optionally copies image files.
98104
func runConverter(cmd *cobra.Command, args []string) error {
99105
if selfUpdateFlag {
100106
if len(args) > 0 {
@@ -148,6 +154,9 @@ func runConverter(cmd *cobra.Command, args []string) error {
148154
return nil
149155
}
150156

157+
// setupSoxCommand validates the availability of SoX (or Docker) and FFmpeg
158+
// based on the current configuration. It resolves absolute paths when using
159+
// Docker mode and checks for ALAC files when metadata preservation is disabled.
151160
func setupSoxCommand() error {
152161
if config.UseDocker {
153162
// Check if docker is installed
@@ -192,6 +201,8 @@ func setupSoxCommand() error {
192201
return nil
193202
}
194203

204+
// hasALACFiles walks the given directory and returns true if any .m4a file
205+
// (ALAC container) is found, stopping the walk early.
195206
func hasALACFiles(dir string) (bool, error) {
196207
hasALAC := false
197208
err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
@@ -208,6 +219,9 @@ func hasALACFiles(dir string) (bool, error) {
208219
return hasALAC, err
209220
}
210221

222+
// processAudioFiles walks the source directory and processes each audio file
223+
// (FLAC, MP3, or ALAC) according to the current configuration, including
224+
// format enforcement, conversion, and metadata preservation.
211225
func processAudioFiles() error {
212226
return filepath.Walk(config.SourceDir, func(path string, info os.FileInfo, err error) error {
213227
if err != nil {
@@ -298,6 +312,9 @@ func processAudioFiles() error {
298312
})
299313
}
300314

315+
// processAudioFileWithEnforcedFormat handles a single audio file when the
316+
// --enforce-output-format flag is set, routing to the appropriate target
317+
// format handler (FLAC, MP3, or ALAC).
301318
func processAudioFileWithEnforcedFormat(sourcePath, targetPath, sourceExt string) error {
302319
// Get audio info for source file
303320
var audioInfo *AudioInfo
@@ -332,6 +349,9 @@ func processAudioFileWithEnforcedFormat(sourcePath, targetPath, sourceExt string
332349
}
333350
}
334351

352+
// processToFLAC converts the source file to FLAC format according to the
353+
// --enforce-output-format=flac flag. MP3 sources are copied as-is since
354+
// transcoding lossy to lossless is not useful.
335355
func processToFLAC(sourcePath, targetPath, sourceExt string, audioInfo *AudioInfo) error {
336356
// Change target extension to .flac
337357
targetPath = changeExtensionToFlac(targetPath)
@@ -370,6 +390,8 @@ func processToFLAC(sourcePath, targetPath, sourceExt string, audioInfo *AudioInf
370390
return fmt.Errorf("unsupported source format for FLAC conversion: %s", sourceExt)
371391
}
372392

393+
// processToMP3 converts the source file to 320kbps MP3 according to the
394+
// --enforce-output-format=mp3 flag. Already-MP3 files are copied as-is.
373395
func processToMP3(sourcePath, targetPath, sourceExt string, audioInfo *AudioInfo) error {
374396
// Change target extension to .mp3
375397
targetPath = changeExtensionToMP3(targetPath)
@@ -384,6 +406,9 @@ func processToMP3(sourcePath, targetPath, sourceExt string, audioInfo *AudioInfo
384406
return convertToMP3(sourcePath, targetPath, audioInfo)
385407
}
386408

409+
// processToALAC converts the source file to ALAC (M4A) according to the
410+
// --enforce-output-format=alac flag. Already-ALAC files at 16-bit are
411+
// copied as-is; MP3 sources are copied without conversion.
387412
func processToALAC(sourcePath, targetPath, sourceExt string, audioInfo *AudioInfo) error {
388413
// Change target extension to .m4a
389414
targetPath = changeExtensionToM4A(targetPath)
@@ -416,6 +441,9 @@ func processToALAC(sourcePath, targetPath, sourceExt string, audioInfo *AudioInf
416441
return fmt.Errorf("unsupported source format for ALAC conversion: %s", sourceExt)
417442
}
418443

444+
// getAudioInfo returns audio information (bit depth, sample rate, format)
445+
// for the given file by dispatching to the appropriate format-specific
446+
// inspector (FLAC via SoX, ALAC via ffprobe).
419447
func getAudioInfo(filePath string) (*AudioInfo, error) {
420448
ext := strings.ToLower(filepath.Ext(filePath))
421449

@@ -426,6 +454,8 @@ func getAudioInfo(filePath string) (*AudioInfo, error) {
426454
}
427455
}
428456

457+
// getFLACInfo runs SoX's --i flag on the given FLAC file and parses the
458+
// output to determine the bit depth and sample rate.
429459
func getFLACInfo(filePath string) (*AudioInfo, error) {
430460
var cmd *exec.Cmd
431461

@@ -454,6 +484,8 @@ func getFLACInfo(filePath string) (*AudioInfo, error) {
454484
return audioInfo, nil
455485
}
456486

487+
// getALACInfo uses ffprobe to extract the sample rate and bit depth from
488+
// an ALAC (M4A) file, supporting both local and Docker execution modes.
457489
func getALACInfo(filePath string) (*AudioInfo, error) {
458490
var cmd *exec.Cmd
459491

@@ -481,6 +513,9 @@ func getALACInfo(filePath string) (*AudioInfo, error) {
481513
return parseALACInfo(string(output))
482514
}
483515

516+
// parseALACInfo parses ffprobe CSV output (sample_rate,bits_per_raw_sample)
517+
// and returns the audio information. It skips lines with invalid or out-of-range
518+
// values and only returns the first valid audio stream found.
484519
func parseALACInfo(info string) (*AudioInfo, error) {
485520
lines := strings.Split(strings.TrimSpace(info), "\n")
486521
if len(lines) == 0 {
@@ -524,21 +559,27 @@ func parseALACInfo(info string) (*AudioInfo, error) {
524559
return nil, fmt.Errorf("no valid audio stream information found")
525560
}
526561

562+
// changeExtensionToFlac replaces the file extension with .flac.
527563
func changeExtensionToFlac(filePath string) string {
528564
ext := filepath.Ext(filePath)
529565
return strings.TrimSuffix(filePath, ext) + ".flac"
530566
}
531567

568+
// changeExtensionToMP3 replaces the file extension with .mp3.
532569
func changeExtensionToMP3(filePath string) string {
533570
ext := filepath.Ext(filePath)
534571
return strings.TrimSuffix(filePath, ext) + ".mp3"
535572
}
536573

574+
// changeExtensionToM4A replaces the file extension with .m4a.
537575
func changeExtensionToM4A(filePath string) string {
538576
ext := filepath.Ext(filePath)
539577
return strings.TrimSuffix(filePath, ext) + ".m4a"
540578
}
541579

580+
// convertToMP3 transcodes the source audio file to 320kbps MP3 using SoX,
581+
// then optionally preserves metadata via FFmpeg. The target sample rate is
582+
// chosen based on the source rate family (48kHz or 44.1kHz).
542583
func convertToMP3(sourcePath, targetPath string, audioInfo *AudioInfo) error {
543584
// MP3 conversion: Use SoX to convert audio, then FFmpeg to preserve metadata
544585
var tempPath string
@@ -598,6 +639,9 @@ func convertToMP3(sourcePath, targetPath string, audioInfo *AudioInfo) error {
598639
return nil
599640
}
600641

642+
// convertToALAC transcodes the source audio file to ALAC (M4A) via a two-step
643+
// process: SoX downsamples to an intermediate FLAC (if needed), then FFmpeg
644+
// encodes to ALAC while preserving metadata from the original file.
601645
func convertToALAC(sourcePath, targetPath string, audioInfo *AudioInfo) error {
602646
// ALAC conversion:
603647
// To preserve the best quality and metadata:
@@ -735,6 +779,8 @@ func convertToALAC(sourcePath, targetPath string, audioInfo *AudioInfo) error {
735779
return nil
736780
}
737781

782+
// processAudioFile dispatches to the correct processing function based on the
783+
// audio format (FLAC or ALAC).
738784
func processAudioFile(sourcePath, targetPath string, audioInfo *AudioInfo, needsConversion bool, bitrateArgs, sampleRateArgs []string) error {
739785
if audioInfo.Format == "alac" {
740786
return processALAC(sourcePath, targetPath, needsConversion, bitrateArgs, sampleRateArgs)
@@ -743,6 +789,9 @@ func processAudioFile(sourcePath, targetPath string, audioInfo *AudioInfo, needs
743789
}
744790
}
745791

792+
// processALAC converts an ALAC file to FLAC. When conversion is needed, it
793+
// uses a two-step process (FFmpeg for format conversion, then SoX for quality
794+
// adjustment). Metadata is preserved via FFmpeg when enabled.
746795
func processALAC(sourcePath, targetPath string, needsConversion bool, bitrateArgs, sampleRateArgs []string) error {
747796
var tempPath string
748797

@@ -863,6 +912,9 @@ func processALAC(sourcePath, targetPath string, needsConversion bool, bitrateArg
863912
return nil
864913
}
865914

915+
// parseAudioInfo parses SoX's --i output to extract the bit depth and sample
916+
// rate from a FLAC file. Returns an AudioInfo with zero values if parsing
917+
// fails silently.
866918
func parseAudioInfo(info string) (*AudioInfo, error) {
867919
audioInfo := &AudioInfo{}
868920
scanner := bufio.NewScanner(strings.NewReader(info))
@@ -889,6 +941,9 @@ func parseAudioInfo(info string) (*AudioInfo, error) {
889941
return audioInfo, nil
890942
}
891943

944+
// determineConversion checks whether the audio file needs bit depth or sample
945+
// rate conversion. It returns the required SoX arguments for both. Files at
946+
// 16-bit/44.1kHz or 16-bit/48kHz do not need conversion.
892947
func determineConversion(info *AudioInfo) (bool, []string, []string) {
893948
needsConversion := false
894949
var bitrateArgs []string
@@ -913,6 +968,9 @@ func determineConversion(info *AudioInfo) (bool, []string, []string) {
913968
return needsConversion, bitrateArgs, sampleRateArgs
914969
}
915970

971+
// processFlac transcodes a FLAC file to reduced bit depth / sample rate
972+
// using SoX, then optionally merges metadata from the source via FFmpeg.
973+
// If no conversion is needed, it copies the file directly.
916974
func processFlac(sourcePath, targetPath string, needsConversion bool, bitrateArgs, sampleRateArgs []string) error {
917975
if !needsConversion {
918976
return copyFile(sourcePath, targetPath)
@@ -981,16 +1039,23 @@ func processFlac(sourcePath, targetPath string, needsConversion bool, bitrateArg
9811039
return nil
9821040
}
9831041

1042+
// getDockerPath converts a host-side file path into a container-side source
1043+
// path by computing the relative path from the source directory.
9841044
func getDockerPath(hostPath string) string {
9851045
relPath := normalizeForDocker(config.SourceDir, hostPath)
9861046
return "/source/" + relPath
9871047
}
9881048

1049+
// getDockerTargetPath converts a host-side file path into a container-side
1050+
// target path by computing the relative path from the target directory.
9891051
func getDockerTargetPath(hostPath string) string {
9901052
relPath := normalizeForDocker(config.TargetDir, hostPath)
9911053
return "/target/" + relPath
9921054
}
9931055

1056+
// normalizeForDocker computes a clean relative path suitable for use inside
1057+
// a Docker volume mount. It strips Windows drive letters and normalizes
1058+
// backslashes to forward slashes.
9941059
func normalizeForDocker(base, path string) string {
9951060
// Convert backslashes to forward slashes first
9961061
base = strings.ReplaceAll(base, "\\", "/")
@@ -1024,6 +1089,10 @@ func normalizeForDocker(base, path string) string {
10241089
}
10251090
return filepath.ToSlash(rel)
10261091
}
1092+
// mergeMetadataWithFFmpeg combines audio from the converted temp file with
1093+
// metadata and cover art from the original source file using FFmpeg. On
1094+
// success the temp file is removed; if NoPreserveMetadata is set it simply
1095+
// renames the temp to the target path.
10271096
func mergeMetadataWithFFmpeg(sourcePath, tempConvertedPath, targetPath string) error {
10281097
if config.NoPreserveMetadata {
10291098
// If not preserving metadata, just rename temp to target
@@ -1074,6 +1143,8 @@ func mergeMetadataWithFFmpeg(sourcePath, tempConvertedPath, targetPath string) e
10741143
return nil
10751144
}
10761145

1146+
// copyImageFiles walks the source directory and copies all JPG and PNG files
1147+
// to the target directory, preserving the directory structure.
10771148
func copyImageFiles() error {
10781149
fmt.Println("Copying image files...")
10791150

@@ -1201,6 +1272,8 @@ func copyFile(src, dst string) error {
12011272
return doCopyFile(src, dst)
12021273
}
12031274

1275+
// GitHubRelease represents a GitHub release API response, containing the
1276+
// tag name used for version comparison in self-update.
12041277
type GitHubRelease struct {
12051278
TagName string `json:"tag_name"`
12061279
}
@@ -1238,6 +1311,9 @@ func compareVersions(v1, v2 string) int {
12381311
return 0
12391312
}
12401313

1314+
// selfUpdate checks the GitHub releases API for a newer version, downloads
1315+
// the matching platform archive, extracts the binary, and replaces the
1316+
// currently running executable with a backup fallback on failure.
12411317
func selfUpdate(client *http.Client) error {
12421318
currentVersion := version
12431319
if currentVersion == "dev" {

0 commit comments

Comments
 (0)