about summary refs log tree commit diff
path: root/pkgs/profpatsch/nman/nman.go
diff options
context:
space:
mode:
authorsternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-02-12 14:05:56 +0100
committersternenseemann <sternenseemann@systemli.org>2021-02-25 19:52:33 +0100
commitcbef421081f1e65b1dcd81c9a6434e69cbc50f8e (patch)
tree64d8bb5209903dc803e5c12c328524c1f7cf64a0 /pkgs/profpatsch/nman/nman.go
parent9f11b3333709364c15a60c38fee9b655728b6c93 (diff)
pkgs/profpatsch/nman: initial rewrite in rust
This is a complete and user interface compatible rewrite of nman.go in
Rust which aleviates a few flaws of the previous implementation:

* Garbage collector roots for both the derivation and the build outputs
  are created in a temporary directory which is cleaned afterwards. This
  prevents a race condition between nman and nix-store --gc and doesn't
  pollute the user's working directory.
* Instead of building just one build output, nman now checks every
  output for the requested man page which fixes nman for derivations
  which have their man pages split between multiple outputs, e. g. man
  and devman.

Future work:

* Improve error messages reported to the user
* Man page
* Implement man page search heuristics if no section is specified:
  Instead of falling back to section 1, all sections should be checked
  for the desired page (in an ascending order?)
Diffstat (limited to 'pkgs/profpatsch/nman/nman.go')
-rw-r--r--pkgs/profpatsch/nman/nman.go137
1 files changed, 0 insertions, 137 deletions
diff --git a/pkgs/profpatsch/nman/nman.go b/pkgs/profpatsch/nman/nman.go
deleted file mode 100644
index b62479a0..00000000
--- a/pkgs/profpatsch/nman/nman.go
+++ /dev/null
@@ -1,137 +0,0 @@
-package main
-
-import (
-	"fmt"
-	"os"
-	"strconv"
-	"log"
-	"bytes"
-	"os/exec"
-	"io/ioutil"
-	"syscall"
-)
-
-var usage = `nman drvAttr [section|page] [page]
-
-Open man pages in a temporary nix-shell.
-1 If one argument is given, the drvAttr & page have the same name.
-2 If two arguments are given and the second arg is
-    a <number>) like 1, but in the man section <number>
-    a <page>  ) like 1, but open the page <page>
-3 If three arguments are given, the order is <drvAttr> <sect> <page>
-`
-
-func lookupManPage(manpath string, manSection int64, manPage string) (int, error) {
-	if manSection < -1 {
-		panic("manSection must not be < -1")
-	}
-	// holy debug printf
-	// fmt.Printf("attr: %s, sect: %d, page: %s\n", drvAttr, manSection, manPage)
-
-	manBin, err := exec.LookPath("man");
-	if err != nil {
-		return 0, fmt.Errorf("man executable not in PATH")
-	}
-
-	var manArgs []string
-	if (manSection == -1) {
-		manArgs = []string{manPage}
-	} else {
-		manArgs = []string{strconv.FormatInt(manSection, 10), manPage}
-	}
-
-	man := exec.Command(manBin, manArgs...)
-
-        man.Env = append(
-		os.Environ(),
-		fmt.Sprintf("MANPATH=%s", manpath))
-	man.Stderr = os.Stderr
-	man.Stdout = os.Stdout
-	err = man.Run()
-	if exiterr, ok := err.(*exec.ExitError); ok {
-		ws := exiterr.Sys().(syscall.WaitStatus)
-		return ws.ExitStatus(), nil
-	} else {
-		return 0, err
-	}
-
-}
-
-func buildManOutput(drvAttr string) (string, error) {
-	nixExpr := fmt.Sprintf(
-		`with import <nixpkgs> {}; %s.man or %s.doc or %s.out or %s`,
-		drvAttr, drvAttr, drvAttr, drvAttr)
-
-	nixBuild := exec.Command("nix-build", "--no-out-link", "-E", nixExpr)
-	nixBuild.Stderr = os.Stderr
-	pipe, err := nixBuild.StdoutPipe()
-	if err != nil { return "", fmt.Errorf("could not access stdout of nix-build: %s", err) }
-
-	err = nixBuild.Start()
-	if err != nil { return "", fmt.Errorf("could not start nix-build: %s", err) }
-
-	out, err := ioutil.ReadAll(pipe)
-	if err != nil { return "", fmt.Errorf("could not read from nix-build: %s", err) }
-
-	lines := bytes.Split(bytes.TrimSpace(out), []byte("\n"))
-	err = nixBuild.Wait()
-	if err != nil { return "", fmt.Errorf("nix-build process died: %s", err) }
-
-	// last line ouf output looks like: /nix/store/abc…-foobar.drv!output
-	drvPath := bytes.Split(lines[len(lines)-1], []byte("!"))[0]
-	if _, err := os.Stat(string(drvPath)); err != nil {
-		return "", fmt.Errorf("%s doesn’t look like an output path: %s", drvPath, err)
-	}
-
-	return string(drvPath), nil
-}
-
-func main() {
-	var manPage string
-	var drvAttr string
-
-	args := os.Args
-
-	// man section or -1 if no man section
-        var manSection int64 = -1
-	if (len(args) >= 3) {
-		i, err := strconv.ParseUint(args[2], 10, 64)
-		if err == nil && i >= 0 {
-			manSection = int64(i)
-		}
-	}
-
-	// the first argument is always a derivation attribute
-	switch len(args) {
-	case 2:
-		// arg is package and drv attr
-		manPage = args[1]
-	case 3:
-		if (manSection == -1) {
-			// like 2, but arg 2 is package
-			manPage = args[2]
-		} else {
-			// man section given, page is arg 1
-			manPage = args[1]
-		}
-	case 4:
-		// arg 2 is manSection, arg 3 is package
-		manPage = args[3]
-	default:
-		fmt.Print(usage)
-		os.Exit(-1)
-	}
-
-	drvAttr = args[1]
-	drvPath, err := buildManOutput(drvAttr)
-	if err != nil {
-		log.Fatal(err)
-	}
-	exitStatus, err := lookupManPage(drvPath + "/share/man", manSection, manPage)
-	if err != nil {
-		log.Fatal(err)
-	}
-
-	os.Exit(exitStatus)
-
-}