github.com/bir3/gocompiler@v0.9.2202/src/cmd/gocmd/internal/vcweb/fossil.go (about)

     1  // Copyright 2017 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package vcweb
     6  
     7  import (
     8  	"fmt"
     9  	"log"
    10  	"net/http"
    11  	"net/http/cgi"
    12  	"os"
    13  	"github.com/bir3/gocompiler/exec"
    14  	"path/filepath"
    15  	"sync"
    16  )
    17  
    18  type fossilHandler struct {
    19  	once		sync.Once
    20  	fossilPath	string
    21  	fossilPathErr	error
    22  }
    23  
    24  func (h *fossilHandler) Available() bool {
    25  	h.once.Do(func() {
    26  		h.fossilPath, h.fossilPathErr = exec.LookPath("fossil")
    27  	})
    28  	return h.fossilPathErr == nil
    29  }
    30  
    31  func (h *fossilHandler) Handler(dir string, env []string, logger *log.Logger) (http.Handler, error) {
    32  	if !h.Available() {
    33  		return nil, ServerNotInstalledError{name: "fossil"}
    34  	}
    35  
    36  	name := filepath.Base(dir)
    37  	db := filepath.Join(dir, name+".fossil")
    38  
    39  	cgiPath := db + ".cgi"
    40  	cgiScript := fmt.Sprintf("#!%s\nrepository: %s\n", h.fossilPath, db)
    41  	if err := os.WriteFile(cgiPath, []byte(cgiScript), 0755); err != nil {
    42  		return nil, err
    43  	}
    44  
    45  	handler := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
    46  		if _, err := os.Stat(db); err != nil {
    47  			http.Error(w, err.Error(), http.StatusInternalServerError)
    48  			return
    49  		}
    50  		ch := &cgi.Handler{
    51  			Env:	env,
    52  			Logger:	logger,
    53  			Path:	h.fossilPath,
    54  			Args:	[]string{cgiPath},
    55  			Dir:	dir,
    56  		}
    57  		ch.ServeHTTP(w, req)
    58  	})
    59  
    60  	return handler, nil
    61  }