103 lines
3.4 KiB
Go
103 lines
3.4 KiB
Go
|
package otbuiltin
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"unsafe"
|
||
|
|
||
|
glib "github.com/ostreedev/ostree-go/pkg/glibobject"
|
||
|
)
|
||
|
|
||
|
// #cgo pkg-config: ostree-1
|
||
|
// #include <stdlib.h>
|
||
|
// #include <glib.h>
|
||
|
// #include <ostree.h>
|
||
|
// #include "builtin.go.h"
|
||
|
import "C"
|
||
|
|
||
|
// Global variable for options
|
||
|
var checkoutOpts checkoutOptions
|
||
|
|
||
|
// Contains all of the options for checking commits out of
|
||
|
// an ostree repo
|
||
|
type checkoutOptions struct {
|
||
|
UserMode bool // Do not change file ownership or initialize extended attributes
|
||
|
Union bool // Keep existing directories and unchanged files, overwriting existing filesystem
|
||
|
AllowNoent bool // Do nothing if the specified filepath does not exist
|
||
|
DisableCache bool // Do not update or use the internal repository uncompressed object caceh
|
||
|
Whiteouts bool // Process 'whiteout' (docker style) entries
|
||
|
RequireHardlinks bool // Do not fall back to full copies if hard linking fails
|
||
|
Subpath string // Checkout sub-directory path
|
||
|
FromFile string // Process many checkouts from the given file
|
||
|
}
|
||
|
|
||
|
// Instantiates and returns a checkoutOptions struct with default values set
|
||
|
func NewCheckoutOptions() checkoutOptions {
|
||
|
return checkoutOptions{}
|
||
|
}
|
||
|
|
||
|
// Checks out a commit with the given ref from a repository at the location of repo path to to the destination. Returns an error if the checkout could not be processed
|
||
|
func Checkout(repoPath, destination, commit string, opts checkoutOptions) error {
|
||
|
checkoutOpts = opts
|
||
|
|
||
|
var cancellable *glib.GCancellable
|
||
|
ccommit := C.CString(commit)
|
||
|
defer C.free(unsafe.Pointer(ccommit))
|
||
|
var gerr = glib.NewGError()
|
||
|
cerr := (*C.GError)(gerr.Ptr())
|
||
|
defer C.free(unsafe.Pointer(cerr))
|
||
|
|
||
|
repoPathc := C.g_file_new_for_path(C.CString(repoPath))
|
||
|
defer C.g_object_unref(C.gpointer(repoPathc))
|
||
|
crepo := C.ostree_repo_new(repoPathc)
|
||
|
if !glib.GoBool(glib.GBoolean(C.ostree_repo_open(crepo, (*C.GCancellable)(cancellable.Ptr()), &cerr))) {
|
||
|
return generateError(cerr)
|
||
|
}
|
||
|
|
||
|
if strings.Compare(checkoutOpts.FromFile, "") != 0 {
|
||
|
err := processManyCheckouts(crepo, destination, cancellable)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
} else {
|
||
|
var resolvedCommit *C.char
|
||
|
defer C.free(unsafe.Pointer(resolvedCommit))
|
||
|
if !glib.GoBool(glib.GBoolean(C.ostree_repo_resolve_rev(crepo, ccommit, C.FALSE, &resolvedCommit, &cerr))) {
|
||
|
return generateError(cerr)
|
||
|
}
|
||
|
err := processOneCheckout(crepo, resolvedCommit, checkoutOpts.Subpath, destination, cancellable)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Processes one checkout from the repo
|
||
|
func processOneCheckout(crepo *C.OstreeRepo, resolvedCommit *C.char, subpath, destination string, cancellable *glib.GCancellable) error {
|
||
|
cdest := C.CString(destination)
|
||
|
defer C.free(unsafe.Pointer(cdest))
|
||
|
var gerr = glib.NewGError()
|
||
|
cerr := (*C.GError)(gerr.Ptr())
|
||
|
defer C.free(unsafe.Pointer(cerr))
|
||
|
var repoCheckoutAtOptions C.OstreeRepoCheckoutAtOptions
|
||
|
|
||
|
if checkoutOpts.UserMode {
|
||
|
repoCheckoutAtOptions.mode = C.OSTREE_REPO_CHECKOUT_MODE_USER
|
||
|
}
|
||
|
if checkoutOpts.Union {
|
||
|
repoCheckoutAtOptions.overwrite_mode = C.OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES
|
||
|
}
|
||
|
|
||
|
checkedOut := glib.GoBool(glib.GBoolean(C.ostree_repo_checkout_at(crepo, &repoCheckoutAtOptions, C._at_fdcwd(), cdest, resolvedCommit, nil, &cerr)))
|
||
|
if !checkedOut {
|
||
|
return generateError(cerr)
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// process many checkouts
|
||
|
func processManyCheckouts(crepo *C.OstreeRepo, target string, cancellable *glib.GCancellable) error {
|
||
|
return nil
|
||
|
}
|