mirror of
				https://github.com/aler9/rtsp-simple-server
				synced 2025-10-31 19:13:22 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			144 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package main contains an utility to get the server version
 | |
| package main
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"log"
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"strconv"
 | |
| 	"strings"
 | |
| 
 | |
| 	"github.com/go-git/go-billy/v5/osfs"
 | |
| 	"github.com/go-git/go-git/v5"
 | |
| 	"github.com/go-git/go-git/v5/plumbing"
 | |
| 	"github.com/go-git/go-git/v5/plumbing/cache"
 | |
| 	"github.com/go-git/go-git/v5/plumbing/object"
 | |
| 	"github.com/go-git/go-git/v5/storage/filesystem"
 | |
| )
 | |
| 
 | |
| // Golang version of git describe --tags
 | |
| func gitDescribeTags(repo *git.Repository) (string, error) {
 | |
| 	head, err := repo.Head()
 | |
| 	if err != nil {
 | |
| 		return "", fmt.Errorf("failed to get HEAD: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	tagIterator, err := repo.Tags()
 | |
| 	if err != nil {
 | |
| 		return "", fmt.Errorf("failed to get tags: %w", err)
 | |
| 	}
 | |
| 	defer tagIterator.Close()
 | |
| 
 | |
| 	tags := make(map[plumbing.Hash]*plumbing.Reference)
 | |
| 
 | |
| 	err = tagIterator.ForEach(func(t *plumbing.Reference) error {
 | |
| 		if to, err2 := repo.TagObject(t.Hash()); err2 == nil {
 | |
| 			tags[to.Target] = t
 | |
| 		} else {
 | |
| 			tags[t.Hash()] = t
 | |
| 		}
 | |
| 		return nil
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return "", fmt.Errorf("failed to iterate tags: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	cIter, err := repo.Log(&git.LogOptions{From: head.Hash()})
 | |
| 	if err != nil {
 | |
| 		return "", fmt.Errorf("failed to get log: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	i := 0
 | |
| 
 | |
| 	for {
 | |
| 		var commit *object.Commit
 | |
| 		commit, err = cIter.Next()
 | |
| 		if err != nil {
 | |
| 			return "", fmt.Errorf("failed to get next commit: %w", err)
 | |
| 		}
 | |
| 
 | |
| 		if str, ok := tags[commit.Hash]; ok {
 | |
| 			label := strings.TrimPrefix(string(str.Name()), "refs/tags/")
 | |
| 
 | |
| 			if i != 0 {
 | |
| 				label += "-" + strconv.FormatInt(int64(i), 10) + "-" + head.Hash().String()[:8]
 | |
| 			}
 | |
| 
 | |
| 			return label, nil
 | |
| 		}
 | |
| 
 | |
| 		i++
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func tagFromGit() error {
 | |
| 	// [git.PlainOpen] uses a ChrootOS that limits filesystem access to the .git directory only.
 | |
| 	//
 | |
| 	// Unfortunately, this can cause issues with package build environments such as Arch Linux's,
 | |
| 	// where .git/objects/info/alternates points to a directory outside of the .git directory.
 | |
| 	//
 | |
| 	// To work around this, specify an AlternatesFS that allows access to the entire filesystem.
 | |
| 	dotGitAbs, _ := filepath.Abs("../../.git")
 | |
| 	storerFs := osfs.New(dotGitAbs, osfs.WithBoundOS())
 | |
| 	storer := filesystem.NewStorageWithOptions(storerFs, cache.NewObjectLRUDefault(), filesystem.Options{
 | |
| 		AlternatesFS: osfs.New("/", osfs.WithBoundOS()),
 | |
| 	})
 | |
| 	workTreeAbs, _ := filepath.Abs("../../")
 | |
| 	worktreeFs := osfs.New(workTreeAbs, osfs.WithBoundOS())
 | |
| 	repo, err := git.Open(storer, worktreeFs)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("failed to open repository: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	version, err := gitDescribeTags(repo)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("failed to get version: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	wt, err := repo.Worktree()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("failed to get worktree: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	status, err := wt.Status()
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("failed to get status: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	if !status.IsClean() {
 | |
| 		version += "-dirty"
 | |
| 	}
 | |
| 
 | |
| 	err = os.WriteFile("VERSION", []byte(version), 0o644)
 | |
| 	if err != nil {
 | |
| 		return fmt.Errorf("failed to write version file: %w", err)
 | |
| 	}
 | |
| 
 | |
| 	log.Printf("ok (%s)", version)
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func do() error {
 | |
| 	log.Println("getting mediamtx version...")
 | |
| 
 | |
| 	err := tagFromGit()
 | |
| 	if err != nil {
 | |
| 		log.Println("WARN: cannot get tag from .git folder, using v0.0.0 as version")
 | |
| 		err = os.WriteFile("VERSION", []byte("v0.0.0"), 0o644)
 | |
| 		if err != nil {
 | |
| 			return fmt.Errorf("failed to write version file: %w", err)
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func main() {
 | |
| 	err := do()
 | |
| 	if err != nil {
 | |
| 		log.Printf("ERR: %v", err)
 | |
| 		os.Exit(1)
 | |
| 	}
 | |
| }
 | 
