<commit_before>package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"time"

	"github.com/Sirupsen/logrus"
	canonicaljson "github.com/docker/go/canonical/json"
	"github.com/docker/notary"
	"github.com/docker/notary/client/changelist"
	"github.com/docker/notary/cryptoservice"
	store "github.com/docker/notary/storage"
	"github.com/docker/notary/trustpinning"
	"github.com/docker/notary/tuf"
	"github.com/docker/notary/tuf/data"
	"github.com/docker/notary/tuf/signed"
	"github.com/docker/notary/tuf/utils"
)

const (
	tufDir = "tuf"

	// SignWithAllOldVersions is a sentinel constant for LegacyVersions flag
	SignWithAllOldVersions = -1
)

func init() {
	data.SetDefaultExpiryTimes(data.NotaryDefaultExpiries)
}

// NotaryRepository stores all the information needed to operate on a notary
// repository.
type NotaryRepository struct {
	baseDir        string
	gun            data.GUN
	baseURL        string
	changelist     changelist.Changelist
	cache          store.MetadataStore
	remoteStore    store.RemoteStore
	CryptoService  signed.CryptoService
	tufRepo        *tuf.Repo
	invalid        *tuf.Repo // known data that was parsable but deemed invalid
	roundTrip      http.RoundTripper
	trustPinning   trustpinning.TrustPinConfig
	LegacyVersions int // number of versions back to fetch roots to sign with
}

// NewFileCachedNotaryRepository is a wrapper for NewNotaryRepository that initializes
// a file cache from the provided repository, local config information and a crypto service.
// It also retrieves the remote store associated to the base directory under where all the
// trust files will be stored and the specified GUN.
func NewFileCachedNotaryRepository(baseDir string, gun data.GUN, baseURL string, rt http.RoundTripper,
	retriever notary.PassRetriever, trustPinning trustpinning.TrustPinConfig) (
	*NotaryRepository, error) {

	cache, err := store.NewFileStore(
		filepath.Join(baseDir, tufDir, filepath.FromSlash(gun.String()), "metadata"),
		"json",
	)
	if err != nil {
		return nil, err
	}

	keyStores, err := getKeyStores(baseDir, retriever)
	if err != nil {
		return nil, err
	}

	cryptoService := cryptoservice.NewCryptoService(keyStores...)

	remoteStore, err := getRemoteStore(baseURL, gun, rt)
	if err != nil {
		// baseURL is syntactically invalid
		return nil, err
	}

	cl, err := changelist.NewFileChangelist(filepath.Join(
		filepath.Join(baseDir, tufDir, filepath.FromSlash(gun.String()), "changelist"),
	))
	if err != nil {
		return nil, err
	}

	return NewNotaryRepository(baseDir, gun, baseURL, remoteStore, cache, trustPinning, cryptoService, cl)
}

// NewNotaryRepository is the base method that returns a new notary repository.
// It takes the base directory under where all the trust files will be stored
// (This is normally defaults to "~/.notary" or "~/.docker/trust" when enabling
// docker content trust).
// It expects an initialized remote store and cache.
func NewNotaryRepository(baseDir string, gun data.GUN, baseURL string, remoteStore store.RemoteStore, cache store.MetadataStore,
	trustPinning trustpinning.TrustPinConfig, cryptoService signed.CryptoService, cl changelist.Changelist) (
	*NotaryRepository, error) {

	// Repo's remote store is either a valid remote store or an OfflineStore
	if remoteStore == nil {
		remoteStore = store.OfflineStore{}
	}

	nRepo := &NotaryRepository{
		gun:            gun,
		baseURL:        baseURL,
		baseDir:        baseDir,
		changelist:     cl,
		cache:          cache,
		remoteStore:    remoteStore,
		CryptoService:  cryptoService,
		trustPinning:   trustPinning,
		LegacyVersions: 0, // By default, don't sign with legacy roles
	}

	return nRepo, nil
}

// GetGUN is a getter for the GUN object from a NotaryRepository
func (r *NotaryRepository) GetGUN() data.GUN {
	return r.gun
}

// Target represents a simplified version of the data TUF operates on, so external
// applications don't have to depend on TUF data types.
type Target struct {
	Name   string                    // the name of the target
	Hashes data.Hashes               // the hash of the target
	Length int64                     // the size in bytes of the target
	Custom *canonicaljson.RawMessage // the custom data provided to describe the file at TARGETPATH
}
<commit_msg>client: check for nil cache in constructor<commit_after>package client

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"regexp"
	"time"

	"github.com/Sirupsen/logrus"
	canonicaljson "github.com/docker/go/canonical/json"
	"github.com/docker/notary"
	"github.com/docker/notary/client/changelist"
	"github.com/docker/notary/cryptoservice"
	store "github.com/docker/notary/storage"
	"github.com/docker/notary/trustpinning"
	"github.com/docker/notary/tuf"
	"github.com/docker/notary/tuf/data"
	"github.com/docker/notary/tuf/signed"
	"github.com/docker/notary/tuf/utils"
)

const (
	tufDir = "tuf"

	// SignWithAllOldVersions is a sentinel constant for LegacyVersions flag
	SignWithAllOldVersions = -1
)

func init() {
	data.SetDefaultExpiryTimes(data.NotaryDefaultExpiries)
}

// NotaryRepository stores all the information needed to operate on a notary
// repository.
type NotaryRepository struct {
	baseDir        string
	gun            data.GUN
	baseURL        string
	changelist     changelist.Changelist
	cache          store.MetadataStore
	remoteStore    store.RemoteStore
	CryptoService  signed.CryptoService
	tufRepo        *tuf.Repo
	invalid        *tuf.Repo // known data that was parsable but deemed invalid
	roundTrip      http.RoundTripper
	trustPinning   trustpinning.TrustPinConfig
	LegacyVersions int // number of versions back to fetch roots to sign with
}

// NewFileCachedNotaryRepository is a wrapper for NewNotaryRepository that initializes
// a file cache from the provided repository, local config information and a crypto service.
// It also retrieves the remote store associated to the base directory under where all the
// trust files will be stored and the specified GUN.
func NewFileCachedNotaryRepository(baseDir string, gun data.GUN, baseURL string, rt http.RoundTripper,
	retriever notary.PassRetriever, trustPinning trustpinning.TrustPinConfig) (
	*NotaryRepository, error) {

	cache, err := store.NewFileStore(
		filepath.Join(baseDir, tufDir, filepath.FromSlash(gun.String()), "metadata"),
		"json",
	)
	if err != nil {
		return nil, err
	}

	keyStores, err := getKeyStores(baseDir, retriever)
	if err != nil {
		return nil, err
	}

	cryptoService := cryptoservice.NewCryptoService(keyStores...)

	remoteStore, err := getRemoteStore(baseURL, gun, rt)
	if err != nil {
		// baseURL is syntactically invalid
		return nil, err
	}

	cl, err := changelist.NewFileChangelist(filepath.Join(
		filepath.Join(baseDir, tufDir, filepath.FromSlash(gun.String()), "changelist"),
	))
	if err != nil {
		return nil, err
	}

	return NewNotaryRepository(baseDir, gun, baseURL, remoteStore, cache, trustPinning, cryptoService, cl)
}

// NewNotaryRepository is the base method that returns a new notary repository.
// It takes the base directory under where all the trust files will be stored
// (This is normally defaults to "~/.notary" or "~/.docker/trust" when enabling
// docker content trust).
// It expects an initialized cache. In case of a nil remote store, a default
// offline store is used.
func NewNotaryRepository(baseDir string, gun data.GUN, baseURL string, remoteStore store.RemoteStore, cache store.MetadataStore,
	trustPinning trustpinning.TrustPinConfig, cryptoService signed.CryptoService, cl changelist.Changelist) (
	*NotaryRepository, error) {

	// Repo's remote store is either a valid remote store or an OfflineStore
	if remoteStore == nil {
		remoteStore = store.OfflineStore{}
	}

	if cache == nil {
		return nil, fmt.Errorf("got an invalid cache (nil metadata store)")
	}

	nRepo := &NotaryRepository{
		gun:            gun,
		baseURL:        baseURL,
		baseDir:        baseDir,
		changelist:     cl,
		cache:          cache,
		remoteStore:    remoteStore,
		CryptoService:  cryptoService,
		trustPinning:   trustPinning,
		LegacyVersions: 0, // By default, don't sign with legacy roles
	}

	return nRepo, nil
}

// GetGUN is a getter for the GUN object from a NotaryRepository
func (r *NotaryRepository) GetGUN() data.GUN {
	return r.gun
}

// Target represents a simplified version of the data TUF operates on, so external
// applications don't have to depend on TUF data types.
type Target struct {
	Name   string                    // the name of the target
	Hashes data.Hashes               // the hash of the target
	Length int64                     // the size in bytes of the target
	Custom *canonicaljson.RawMessage // the custom data provided to describe the file at TARGETPATH
}

{'fraction_non_alphanumeric': 0.08903798044120992, 'fraction_numerical': 0.0009097111667045713, 'mean_word_length': 3.6781914893617023, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2798381', 'n_tokens_mistral': 2884, 'n_tokens_neox': 2744, 'n_words': 854}