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")
 | 
						|
}
 |