Cleans up a whole bunch of things I wanted to get out of the door right away: * depot internal references to //third_party/nixery have been replaced with //tools/nixery * cleaned up files from Github * fixed SPDX & Copyright headers * code formatting and inclusion in //tools/depotfmt checks Change-Id: Iea79f0fdf3aa04f71741d4f4032f88605ae415bb Reviewed-on: https://cl.tvl.fyi/c/depot/+/5486 Tested-by: BuildkiteCI Reviewed-by: tazjin <tazjin@tvl.su> Autosubmit: tazjin <tazjin@tvl.su>
		
			
				
	
	
		
			148 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
	
		
			3.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright 2022 The TVL Contributors
 | |
| // SPDX-License-Identifier: Apache-2.0
 | |
| package config
 | |
| 
 | |
| import (
 | |
| 	"crypto/sha1"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"os"
 | |
| 	"regexp"
 | |
| 	"strings"
 | |
| 
 | |
| 	log "github.com/sirupsen/logrus"
 | |
| )
 | |
| 
 | |
| // PkgSource represents the source from which the Nix package set used
 | |
| // by Nixery is imported. Users configure the source by setting one of
 | |
| // the supported environment variables.
 | |
| type PkgSource interface {
 | |
| 	// Convert the package source into the representation required
 | |
| 	// for calling Nix.
 | |
| 	Render(tag string) (string, string)
 | |
| 
 | |
| 	// Create a key by which builds for this source and image
 | |
| 	// combination can be cached.
 | |
| 	//
 | |
| 	// The empty string means that this value is not cacheable due
 | |
| 	// to the package source being a moving target (such as a
 | |
| 	// channel).
 | |
| 	CacheKey(pkgs []string, tag string) string
 | |
| }
 | |
| 
 | |
| type GitSource struct {
 | |
| 	repository string
 | |
| }
 | |
| 
 | |
| // Regex to determine whether a git reference is a commit hash or
 | |
| // something else (branch/tag).
 | |
| //
 | |
| // Used to check whether a git reference is cacheable, and to pass the
 | |
| // correct git structure to Nix.
 | |
| //
 | |
| // Note: If a user creates a branch or tag with the name of a commit
 | |
| // and references it intentionally, this heuristic will fail.
 | |
| var commitRegex = regexp.MustCompile(`^[0-9a-f]{40}$`)
 | |
| 
 | |
| func (g *GitSource) Render(tag string) (string, string) {
 | |
| 	args := map[string]string{
 | |
| 		"url": g.repository,
 | |
| 	}
 | |
| 
 | |
| 	// The 'git' source requires a tag to be present. If the user
 | |
| 	// has not specified one, it is assumed that the default
 | |
| 	// 'master' branch should be used.
 | |
| 	if tag == "latest" || tag == "" {
 | |
| 		tag = "master"
 | |
| 	}
 | |
| 
 | |
| 	if commitRegex.MatchString(tag) {
 | |
| 		args["rev"] = tag
 | |
| 	} else {
 | |
| 		args["ref"] = tag
 | |
| 	}
 | |
| 
 | |
| 	j, _ := json.Marshal(args)
 | |
| 
 | |
| 	return "git", string(j)
 | |
| }
 | |
| 
 | |
| func (g *GitSource) CacheKey(pkgs []string, tag string) string {
 | |
| 	// Only full commit hashes can be used for caching, as
 | |
| 	// everything else is potentially a moving target.
 | |
| 	if !commitRegex.MatchString(tag) {
 | |
| 		return ""
 | |
| 	}
 | |
| 
 | |
| 	unhashed := strings.Join(pkgs, "") + tag
 | |
| 	hashed := fmt.Sprintf("%x", sha1.Sum([]byte(unhashed)))
 | |
| 
 | |
| 	return hashed
 | |
| }
 | |
| 
 | |
| type NixChannel struct {
 | |
| 	channel string
 | |
| }
 | |
| 
 | |
| func (n *NixChannel) Render(tag string) (string, string) {
 | |
| 	return "nixpkgs", n.channel
 | |
| }
 | |
| 
 | |
| func (n *NixChannel) CacheKey(pkgs []string, tag string) string {
 | |
| 	// Since Nix channels are downloaded from the nixpkgs-channels
 | |
| 	// Github, users can specify full commit hashes as the
 | |
| 	// "channel", in which case builds are cacheable.
 | |
| 	if !commitRegex.MatchString(n.channel) {
 | |
| 		return ""
 | |
| 	}
 | |
| 
 | |
| 	unhashed := strings.Join(pkgs, "") + n.channel
 | |
| 	hashed := fmt.Sprintf("%x", sha1.Sum([]byte(unhashed)))
 | |
| 
 | |
| 	return hashed
 | |
| }
 | |
| 
 | |
| type PkgsPath struct {
 | |
| 	path string
 | |
| }
 | |
| 
 | |
| func (p *PkgsPath) Render(tag string) (string, string) {
 | |
| 	return "path", p.path
 | |
| }
 | |
| 
 | |
| func (p *PkgsPath) CacheKey(pkgs []string, tag string) string {
 | |
| 	// Path-based builds are not currently cacheable because we
 | |
| 	// have no local hash of the package folder's state easily
 | |
| 	// available.
 | |
| 	return ""
 | |
| }
 | |
| 
 | |
| // Retrieve a package source from the environment. If no source is
 | |
| // specified, the Nix code will default to a recent NixOS channel.
 | |
| func pkgSourceFromEnv() (PkgSource, error) {
 | |
| 	if channel := os.Getenv("NIXERY_CHANNEL"); channel != "" {
 | |
| 		log.WithField("channel", channel).Info("using Nix package set from Nix channel or commit")
 | |
| 
 | |
| 		return &NixChannel{
 | |
| 			channel: channel,
 | |
| 		}, nil
 | |
| 	}
 | |
| 
 | |
| 	if git := os.Getenv("NIXERY_PKGS_REPO"); git != "" {
 | |
| 		log.WithField("repo", git).Info("using Nix package set from git repository")
 | |
| 
 | |
| 		return &GitSource{
 | |
| 			repository: git,
 | |
| 		}, nil
 | |
| 	}
 | |
| 
 | |
| 	if path := os.Getenv("NIXERY_PKGS_PATH"); path != "" {
 | |
| 		log.WithField("path", path).Info("using Nix package set at local path")
 | |
| 
 | |
| 		return &PkgsPath{
 | |
| 			path: path,
 | |
| 		}, nil
 | |
| 	}
 | |
| 
 | |
| 	return nil, fmt.Errorf("no valid package source has been specified")
 | |
| }
 |