Commit 9c0de4f7 authored by Mickaël Desfrênes's avatar Mickaël Desfrênes
Browse files

fix feed

parent c46d5437
Loading
Loading
Loading
Loading
+20 −23
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@ import (
//go:embed max_releases.json
var fallbackReleases []byte

const version = "0.3.1"
const version = "0.3.2"

const maxConfigFile = "config.xml"
const baseXDistro = "https://files.basex.org/releases/11.7/BaseX117.zip"
@@ -2303,7 +2303,8 @@ func runFeed(feedPath, directory string, verbose bool) error {
	}

	if stat.Mode().IsRegular() {
		cmd := exec.Command(javaBin, "-cp", cpPaths(abs), "-Xmx2g", "org.basex.BaseX", fmt.Sprintf("db:put('max', '%s', '%s')", feedAbs, filepath.Base(feedAbs)))
		query := fmt.Sprintf("db:put('max', '%s', '%s')", feedAbs, filepath.Base(feedAbs))
		cmd := exec.Command(javaBin, "-cp", cpPaths(abs), "-Xmx2g", "org.basex.BaseX", query)
		cmd.Stdout = os.Stdout
		cmd.Stderr = os.Stderr
		if verbose {
@@ -2313,27 +2314,23 @@ func runFeed(feedPath, directory string, verbose bool) error {
		return cmd.Run()
	}

	offset := len(feedAbs)
	return filepath.WalkDir(feedAbs, func(p string, d fs.DirEntry, err error) error {
		if err != nil {
			return err
		}
		if d.IsDir() {
			return nil
		}
		if strings.ToLower(filepath.Ext(p)) != ".xml" {
			return nil
		}
		rel := p[offset:]
		cmd := exec.Command(javaBin, "-cp", cpPaths(abs), "-Xmx2g", "org.basex.BaseX", fmt.Sprintf("db:put('max', '%s', '%s')", p, rel))
	feedDir := ensureTrailingPathSeparator(feedAbs)
	query := fmt.Sprintf("db:put('max', '%s', '')", feedDir)
	cmd := exec.Command(javaBin, "-cp", cpPaths(abs), "-Xmx2g", "org.basex.BaseX", query)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	if verbose {
		fmt.Println(formatCommand(cmd))
	}
		fmt.Println(p)
	fmt.Println(feedDir)
	return cmd.Run()
	})
}

func ensureTrailingPathSeparator(path string) string {
	if strings.HasSuffix(path, string(os.PathSeparator)) {
		return path
	}
	return path + string(os.PathSeparator)
}

func formatCommand(cmd *exec.Cmd) string {
+129 −0
Original line number Diff line number Diff line
@@ -2,7 +2,9 @@ package main

import (
	"archive/tar"
	"bufio"
	"compress/gzip"
	"fmt"
	"net/url"
	"os"
	"path/filepath"
@@ -158,3 +160,130 @@ func TestExtractTarGzPreservesExecutableBit(t *testing.T) {
		t.Fatalf("expected executable mode on %s, got %v", extracted, info.Mode())
	}
}

func TestFeedCommandRunsForFileAndDirectory(t *testing.T) {
	if runtime.GOOS == "windows" {
		t.Skip("test uses a shell script as fake bundled java")
	}

	tmpHome := t.TempDir()
	prevHome := userMaxDir
	prevCache := cacheDir
	userMaxDir = tmpHome
	cacheDir = filepath.Join(userMaxDir, "cache")
	t.Cleanup(func() {
		userMaxDir = prevHome
		cacheDir = prevCache
	})

	oldWD, err := os.Getwd()
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(func() {
		_ = os.Chdir(oldWD)
	})

	projectDir := filepath.Join(t.TempDir(), "project")
	if err := os.MkdirAll(projectDir, 0o755); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(projectDir, maxConfigFile), []byte(configInitTemplate), 0o644); err != nil {
		t.Fatal(err)
	}

	feedFile := filepath.Join(projectDir, "single.xml")
	if err := os.WriteFile(feedFile, []byte("<root/>"), 0o644); err != nil {
		t.Fatal(err)
	}

	feedDir := filepath.Join(projectDir, "batch")
	if err := os.MkdirAll(feedDir, 0o755); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(feedDir, "a.xml"), []byte("<a/>"), 0o644); err != nil {
		t.Fatal(err)
	}
	if err := os.WriteFile(filepath.Join(feedDir, "b.xml"), []byte("<b/>"), 0o644); err != nil {
		t.Fatal(err)
	}

	logPath := filepath.Join(t.TempDir(), "java.log")
	t.Setenv("CLIMAX_TEST_JAVA_LOG", logPath)
	if err := installFakeBundledJava(tmpHome); err != nil {
		t.Fatal(err)
	}

	root := newRootCmd()
	root.SetArgs([]string{"feed", feedFile, "--directory", projectDir})
	if err := root.Execute(); err != nil {
		t.Fatalf("feed command failed for file input: %v", err)
	}

	root = newRootCmd()
	root.SetArgs([]string{"feed", feedDir, "--directory", projectDir})
	if err := root.Execute(); err != nil {
		t.Fatalf("feed command failed for directory input: %v", err)
	}

	lines, err := readLogLines(logPath)
	if err != nil {
		t.Fatal(err)
	}
	if len(lines) != 4 {
		t.Fatalf("expected 4 java invocations (2 per feed run), got %d:\n%v", len(lines), lines)
	}

	createDBQuery := "if(not(db:exists('max'))) then db:create('max') else ()"
	if !strings.Contains(lines[0], createDBQuery) || !strings.Contains(lines[2], createDBQuery) {
		t.Fatalf("expected create-db query in first and third invocation, got:\n%v", lines)
	}

	if !strings.Contains(lines[1], fmt.Sprintf("db:put('max', '%s', '%s')", feedFile, filepath.Base(feedFile))) {
		t.Fatalf("expected single-file db:put query in second invocation, got:\n%s", lines[1])
	}

	feedDirWithSep := ensureTrailingPathSeparator(feedDir)
	if !strings.Contains(lines[3], fmt.Sprintf("db:put('max', '%s', '')", feedDirWithSep)) {
		t.Fatalf("expected directory db:put query in fourth invocation, got:\n%s", lines[3])
	}
	if strings.Contains(lines[3], "a.xml") || strings.Contains(lines[3], "b.xml") {
		t.Fatalf("expected no per-file db:put during directory feed, got:\n%s", lines[3])
	}
}

func installFakeBundledJava(home string) error {
	javaBin := bundledJavaPath(filepath.Join(home, "jdk"), currentSystem())
	if javaBin == "" {
		return fmt.Errorf("no bundled java path for system %s", currentSystem())
	}
	if err := os.MkdirAll(filepath.Dir(javaBin), 0o755); err != nil {
		return err
	}
	script := "#!/bin/sh\n" +
		"if [ -n \"$CLIMAX_TEST_JAVA_LOG\" ]; then\n" +
		"  printf '%s\\n' \"$*\" >> \"$CLIMAX_TEST_JAVA_LOG\"\n" +
		"fi\n"
	return os.WriteFile(javaBin, []byte(script), 0o755)
}

func readLogLines(path string) ([]string, error) {
	f, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	var lines []string
	scanner := bufio.NewScanner(f)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line != "" {
			lines = append(lines, line)
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return lines, nil
}