Skip to content

Commit

Permalink
content handlers
Browse files Browse the repository at this point in the history
Signed-off-by: Xiaoxuan Wang <xiaoxuanwang@microsoft.com>
  • Loading branch information
Xiaoxuan Wang committed Sep 25, 2024
1 parent 5104cc9 commit a9b1164
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 43 deletions.
7 changes: 6 additions & 1 deletion cmd/oras/internal/display/content/discard.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ func (discardHandler) OnContentFetched(ocispec.Descriptor, []byte) error {
return nil
}

// OnContentCreated implements ManifestIndexCreateHandler.
func (discardHandler) OnContentCreated(content []byte) error {
return nil
}

// NewDiscardHandler returns a new discard handler.
func NewDiscardHandler() ManifestFetchHandler {
func NewDiscardHandler() discardHandler {
return discardHandler{}
}
9 changes: 9 additions & 0 deletions cmd/oras/internal/display/content/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,12 @@ type ManifestFetchHandler interface {
// OnContentFetched is called after the manifest content is fetched.
OnContentFetched(desc ocispec.Descriptor, content []byte) error
}

// ManifestIndexCreateHandler handles raw output for manifest index create events.
type ManifestIndexCreateHandler interface {
// OnContentCreated is called after the index content is created.
OnContentCreated(content []byte) error
}

// ManifestIndexUpdateHandler handles raw output for manifest index update events.
type ManifestIndexUpdateHandler ManifestIndexCreateHandler
54 changes: 54 additions & 0 deletions cmd/oras/internal/display/content/manifest_index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package content

import (
"fmt"
"io"
"os"

"oras.land/oras/cmd/oras/internal/output"
)

// manifestIndexCreate handles raw content output.
type manifestIndexCreate struct {
pretty bool
stdout io.Writer
outputPath string
}

// OnContentCreated is called after index content is created.
func (h *manifestIndexCreate) OnContentCreated(manifest []byte) error {
out := h.stdout
if h.outputPath != "-" && h.outputPath != "" {
f, err := os.Create(h.outputPath)
if err != nil {
return fmt.Errorf("failed to open %q: %w", h.outputPath, err)
}
defer f.Close()
out = f
}
return output.PrintJSON(out, manifest, h.pretty)
}

// NewManifestIndexCreateHandler creates a new handler.
func NewManifestIndexCreateHandler(out io.Writer, pretty bool, outputPath string) ManifestIndexCreateHandler {
return &manifestIndexCreate{
pretty: pretty,
stdout: out,
outputPath: outputPath,
}
}
50 changes: 40 additions & 10 deletions cmd/oras/internal/display/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,26 +174,56 @@ func NewManifestPushHandler(printer *output.Printer) metadata.ManifestPushHandle
return text.NewManifestPushHandler(printer)
}

// NewManifestIndexCreateHandler returns status and metadata handlers for index create command.
func NewManifestIndexCreateHandler(outputPath string, printer *output.Printer) (status.ManifestIndexCreateHandler, metadata.ManifestIndexCreateHandler, error) {
// NewManifestIndexCreateHandler returns status, metadata and content handlers for index create command.
func NewManifestIndexCreateHandler(outputPath string, printer *output.Printer, pretty bool) (
status.ManifestIndexCreateHandler,
metadata.ManifestIndexCreateHandler,
content.ManifestIndexCreateHandler,
error) {
var statusHandler status.ManifestIndexCreateHandler
if outputPath == "-" {
var metadataHandler metadata.ManifestIndexCreateHandler
var contentHandler content.ManifestIndexCreateHandler
switch outputPath {
case "":
statusHandler = status.NewTextManifestIndexCreateHandler(printer)
metadataHandler = text.NewManifestIndexCreateHandler(printer)
contentHandler = content.NewDiscardHandler()
case "-":
statusHandler = status.NewDiscardHandler()
} else {
metadataHandler = metadata.NewDiscardHandler()
contentHandler = content.NewManifestIndexCreateHandler(printer, pretty, outputPath)
default:
statusHandler = status.NewTextManifestIndexCreateHandler(printer)
metadataHandler = text.NewManifestIndexCreateHandler(printer)
contentHandler = content.NewManifestIndexCreateHandler(printer, pretty, outputPath)
}
return statusHandler, text.NewManifestIndexCreateHandler(printer), nil
return statusHandler, metadataHandler, contentHandler, nil
}

// NewManifestIndexUpdateHandler returns status and metadata handlers for index update command.
func NewManifestIndexUpdateHandler(outputPath string, printer *output.Printer) (status.ManifestIndexUpdateHandler, metadata.ManifestIndexUpdateHandler, error) {
// NewManifestIndexUpdateHandler returns status, metadata and content handlers for index update command.
func NewManifestIndexUpdateHandler(outputPath string, printer *output.Printer, pretty bool) (
status.ManifestIndexUpdateHandler,
metadata.ManifestIndexUpdateHandler,
content.ManifestIndexUpdateHandler,
error) {
var statusHandler status.ManifestIndexUpdateHandler
if outputPath == "-" {
var metadataHandler metadata.ManifestIndexUpdateHandler
var contentHandler content.ManifestIndexUpdateHandler
switch outputPath {
case "":
statusHandler = status.NewTextManifestIndexUpdateHandler(printer)
metadataHandler = text.NewManifestIndexCreateHandler(printer)
contentHandler = content.NewDiscardHandler()
case "-":
statusHandler = status.NewDiscardHandler()
} else {
metadataHandler = metadata.NewDiscardHandler()
contentHandler = content.NewManifestIndexCreateHandler(printer, pretty, outputPath)
default:
statusHandler = status.NewTextManifestIndexUpdateHandler(printer)
metadataHandler = text.NewManifestIndexCreateHandler(printer)
contentHandler = content.NewManifestIndexCreateHandler(printer, pretty, outputPath)
}
return statusHandler, text.NewManifestIndexCreateHandler(printer), nil
return statusHandler, metadataHandler, contentHandler, nil
}

// NewCopyHandler returns copy handlers.
Expand Down
15 changes: 14 additions & 1 deletion cmd/oras/internal/display/metadata/discard.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ limitations under the License.

package metadata

import ocispec "github.com/opencontainers/image-spec/specs-go/v1"
import (
"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

type discard struct{}

Expand All @@ -28,3 +31,13 @@ func NewDiscardHandler() discard {
func (discard) OnFetched(string, ocispec.Descriptor, []byte) error {
return nil
}

// OnTagged implements ManifestIndexCreateHandler.
func (discard) OnTagged(desc ocispec.Descriptor, tag string) error {
return nil
}

// OnCompleted implements ManifestIndexCreateHandler.
func (discard) OnCompleted(digest digest.Digest) error {
return nil
}
27 changes: 9 additions & 18 deletions cmd/oras/root/manifest/index/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"strings"

"github.com/opencontainers/go-digest"
"github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -109,7 +107,7 @@ func createIndex(cmd *cobra.Command, opts createOptions) error {
if err != nil {
return err
}
displayStatus, displayMetadata, err := display.NewManifestIndexCreateHandler(opts.outputPath, opts.Printer)
displayStatus, displayMetadata, displayContent, err := display.NewManifestIndexCreateHandler(opts.outputPath, opts.Printer, opts.Pretty.Pretty)
if err != nil {
return err
}
Expand All @@ -133,19 +131,15 @@ func createIndex(cmd *cobra.Command, opts createOptions) error {
if err := displayStatus.OnIndexPacked(descriptor.ShortDigest(desc)); err != nil {
return err
}

switch opts.outputPath {
case "":
err = pushIndex(ctx, displayStatus.OnIndexPushed, displayMetadata.OnCompleted, displayMetadata.OnTagged, target, desc, indexBytes, opts.Reference, opts.extraRefs, opts.AnnotatedReference())
case "-":
err = opts.Output(os.Stdout, indexBytes)
default:
if err := displayMetadata.OnCompleted(desc.Digest); err != nil {
if err := displayContent.OnContentCreated(indexBytes); err != nil {
return err
}
if opts.outputPath == "" {
if err := pushIndex(ctx, displayStatus.OnIndexPushed, displayMetadata.OnTagged, target, desc, indexBytes, opts.Reference, opts.extraRefs, opts.AnnotatedReference()); err != nil {
return err
}
err = os.WriteFile(opts.outputPath, indexBytes, 0666)
}
return err
return displayMetadata.OnCompleted(desc.Digest)
}

func fetchSourceManifests(ctx context.Context, displayStatus status.ManifestIndexCreateHandler, target oras.ReadOnlyTarget, sources []string) ([]ocispec.Descriptor, error) {
Expand Down Expand Up @@ -199,10 +193,7 @@ func getPlatform(ctx context.Context, target oras.ReadOnlyTarget, manifestBytes
return &platform, nil
}

func pushIndex(ctx context.Context,
onIndexPushed func(path string) error,
onCompleted func(digest digest.Digest) error,
onTagged func(desc ocispec.Descriptor, tag string) error,
func pushIndex(ctx context.Context, onIndexPushed func(path string) error, onTagged func(desc ocispec.Descriptor, tag string) error,
target oras.Target, desc ocispec.Descriptor, content []byte, ref string, extraRefs []string, path string) error {
// push the index
var err error
Expand All @@ -223,5 +214,5 @@ func pushIndex(ctx context.Context,
return err
}
}
return onCompleted(desc.Digest)
return nil
}
20 changes: 7 additions & 13 deletions cmd/oras/root/manifest/index/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"context"
"encoding/json"
"fmt"
"os"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
Expand Down Expand Up @@ -114,7 +113,7 @@ func updateIndex(cmd *cobra.Command, opts updateOptions) error {
if err := opts.EnsureReferenceNotEmpty(cmd, true); err != nil {
return err
}
displayStatus, displayMetadata, err := display.NewManifestIndexUpdateHandler(opts.outputPath, opts.Printer)
displayStatus, displayMetadata, displayContent, err := display.NewManifestIndexUpdateHandler(opts.outputPath, opts.Printer, opts.Pretty.Pretty)
if err != nil {
return err
}
Expand All @@ -134,30 +133,25 @@ func updateIndex(cmd *cobra.Command, opts updateOptions) error {
if err != nil {
return err
}

index.Manifests = manifests
indexBytes, err := json.Marshal(index)
if err != nil {
return err
}
desc := content.NewDescriptorFromBytes(index.MediaType, indexBytes)

if err := displayStatus.OnIndexUpdated(desc.Digest); err != nil {
return err
}
path := getPushPath(opts.RawReference, opts.Type, opts.Reference, opts.Path)
switch opts.outputPath {
case "":
err = pushIndex(ctx, displayStatus.OnIndexPushed, displayMetadata.OnCompleted, displayMetadata.OnTagged, target, desc, indexBytes, opts.Reference, opts.tags, path)
case "-":
err = opts.Output(os.Stdout, indexBytes)
default:
if err := displayMetadata.OnCompleted(desc.Digest); err != nil {
if err := displayContent.OnContentCreated(indexBytes); err != nil {
return err
}
if opts.outputPath == "" {
if err := pushIndex(ctx, displayStatus.OnIndexPushed, displayMetadata.OnTagged, target, desc, indexBytes, opts.Reference, opts.tags, path); err != nil {
return err
}
err = os.WriteFile(opts.outputPath, indexBytes, 0666)
}
return err
return displayMetadata.OnCompleted(desc.Digest)
}

func fetchIndex(ctx context.Context, handler status.ManifestIndexUpdateHandler, target oras.ReadOnlyTarget, reference string) (ocispec.Index, error) {
Expand Down

0 comments on commit a9b1164

Please sign in to comment.