Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
// Copyright 2016-2018, Pulumi Corporation.
|
|
|
|
//
|
|
|
|
// 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 asset
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"crypto/sha256"
|
|
|
|
"encoding/hex"
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
2024-05-02 11:32:54 +00:00
|
|
|
"path/filepath"
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/resource/sig"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/contract"
|
|
|
|
"github.com/pulumi/pulumi/sdk/v3/go/common/util/httputil"
|
|
|
|
)
|
|
|
|
|
Asset and Archive can have missing contents (#15736)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
Fixes https://github.com/pulumi/pulumi/issues/15729.
This fixes Assets and Archives to allow four states, as opposed to the
three that https://github.com/pulumi/pulumi/pull/14007 had enforced.
An asset can either be Text, Path, Uri, or none. That is `IsText`,
`IsPath`, and `IsURI` can all return false. Similarly for archives
except with Assets instead of Text.
This happens when a provider returns an Assert (or Archive) with a hash
value set, but no other contents.
The Asset and Archive objects have been updated to handle this case, and
a number of places in the CLI that asserted that one of
IsText/IsPath/IsURI were true have been fixed up to handle the case of
all three being false.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [x] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [x] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [x] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-03-21 12:32:26 +00:00
|
|
|
// Asset is a serialized asset reference. It is a union: thus, at most one of its fields will be non-nil. Several helper
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
// routines exist as members in order to easily interact with the assets referenced by an instance of this type.
|
|
|
|
type Asset struct {
|
|
|
|
// Sig is the unique asset type signature (see properties.go).
|
|
|
|
Sig string `json:"4dabf18193072939515e22adb298388d" yaml:"4dabf18193072939515e22adb298388d"`
|
|
|
|
// Hash is the SHA256 hash of the asset's contents.
|
|
|
|
Hash string `json:"hash,omitempty" yaml:"hash,omitempty"`
|
|
|
|
// Text is set to a non-empty value for textual assets.
|
|
|
|
Text string `json:"text,omitempty" yaml:"text,omitempty"`
|
|
|
|
// Path will contain a non-empty path to the file on the current filesystem for file assets.
|
|
|
|
Path string `json:"path,omitempty" yaml:"path,omitempty"`
|
|
|
|
// URI will contain a non-empty URI (file://, http://, https://, or custom) for URI-backed assets.
|
|
|
|
URI string `json:"uri,omitempty" yaml:"uri,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
const (
|
|
|
|
AssetSig = sig.AssetSig
|
|
|
|
AssetHashProperty = "hash" // the dynamic property for an asset's hash.
|
|
|
|
AssetTextProperty = "text" // the dynamic property for an asset's text.
|
|
|
|
AssetPathProperty = "path" // the dynamic property for an asset's path.
|
|
|
|
AssetURIProperty = "uri" // the dynamic property for an asset's URI.
|
|
|
|
)
|
|
|
|
|
|
|
|
// FromText produces a new asset and its corresponding SHA256 hash from the given text.
|
|
|
|
func FromText(text string) (*Asset, error) {
|
|
|
|
a := &Asset{Sig: AssetSig, Text: text}
|
Asset and Archive can have missing contents (#15736)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
Fixes https://github.com/pulumi/pulumi/issues/15729.
This fixes Assets and Archives to allow four states, as opposed to the
three that https://github.com/pulumi/pulumi/pull/14007 had enforced.
An asset can either be Text, Path, Uri, or none. That is `IsText`,
`IsPath`, and `IsURI` can all return false. Similarly for archives
except with Assets instead of Text.
This happens when a provider returns an Assert (or Archive) with a hash
value set, but no other contents.
The Asset and Archive objects have been updated to handle this case, and
a number of places in the CLI that asserted that one of
IsText/IsPath/IsURI were true have been fixed up to handle the case of
all three being false.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [x] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [x] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [x] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-03-21 12:32:26 +00:00
|
|
|
// Special case the empty string otherwise EnsureHash will fail.
|
|
|
|
if text == "" {
|
|
|
|
a.Hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
|
|
}
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
err := a.EnsureHash()
|
|
|
|
return a, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// FromPath produces a new asset and its corresponding SHA256 hash from the given filesystem path.
|
|
|
|
func FromPath(path string) (*Asset, error) {
|
|
|
|
a := &Asset{Sig: AssetSig, Path: path}
|
|
|
|
err := a.EnsureHash()
|
|
|
|
return a, err
|
|
|
|
}
|
|
|
|
|
2024-05-02 11:32:54 +00:00
|
|
|
// FromPathWithWD produces a new asset and its corresponding SHA256 hash from the given filesystem path.
|
|
|
|
func FromPathWithWD(path string, wd string) (*Asset, error) {
|
|
|
|
a := &Asset{Sig: AssetSig, Path: path}
|
|
|
|
err := a.EnsureHashWithWD(wd)
|
|
|
|
return a, err
|
|
|
|
}
|
|
|
|
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
// FromURI produces a new asset and its corresponding SHA256 hash from the given network URI.
|
|
|
|
func FromURI(uri string) (*Asset, error) {
|
|
|
|
a := &Asset{Sig: AssetSig, URI: uri}
|
|
|
|
err := a.EnsureHash()
|
|
|
|
return a, err
|
|
|
|
}
|
|
|
|
|
Asset and Archive can have missing contents (#15736)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
Fixes https://github.com/pulumi/pulumi/issues/15729.
This fixes Assets and Archives to allow four states, as opposed to the
three that https://github.com/pulumi/pulumi/pull/14007 had enforced.
An asset can either be Text, Path, Uri, or none. That is `IsText`,
`IsPath`, and `IsURI` can all return false. Similarly for archives
except with Assets instead of Text.
This happens when a provider returns an Assert (or Archive) with a hash
value set, but no other contents.
The Asset and Archive objects have been updated to handle this case, and
a number of places in the CLI that asserted that one of
IsText/IsPath/IsURI were true have been fixed up to handle the case of
all three being false.
## Checklist
- [x] I have run `make tidy` to update any new dependencies
- [x] I have run `make lint` to verify my code passes the lint check
- [x] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [x] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [x] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-03-21 12:32:26 +00:00
|
|
|
func (a *Asset) IsText() bool {
|
|
|
|
if a.IsPath() || a.IsURI() {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if a.Text != "" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
// We can't easily tell the difference between an Asset that really has the empty string as its text and one that
|
|
|
|
// has no text at all. If we have a hash we can check if that's the "zero hash" and if so then we know the text is
|
|
|
|
// just empty. If the hash does not equal the empty hash then we know this is a _placeholder_ asset where the text is
|
|
|
|
// just currently not known. If we don't have a hash then we can't tell the difference and assume it's just empty.
|
|
|
|
if a.Hash == "" || a.Hash == "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
func (a *Asset) IsPath() bool { return a.Path != "" }
|
|
|
|
func (a *Asset) IsURI() bool { return a.URI != "" }
|
|
|
|
|
|
|
|
func (a *Asset) GetText() (string, bool) {
|
|
|
|
if a.IsText() {
|
|
|
|
return a.Text, true
|
|
|
|
}
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Asset) GetPath() (string, bool) {
|
|
|
|
if a.IsPath() {
|
|
|
|
return a.Path, true
|
|
|
|
}
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Asset) GetURI() (string, bool) {
|
|
|
|
if a.IsURI() {
|
|
|
|
return a.URI, true
|
|
|
|
}
|
|
|
|
return "", false
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetURIURL returns the underlying URI as a parsed URL, provided it is one. If there was an error parsing the URI, it
|
|
|
|
// will be returned as a non-nil error object.
|
|
|
|
func (a *Asset) GetURIURL() (*url.URL, bool, error) {
|
|
|
|
if uri, isuri := a.GetURI(); isuri {
|
|
|
|
url, err := url.Parse(uri)
|
|
|
|
if err != nil {
|
|
|
|
return nil, true, err
|
|
|
|
}
|
|
|
|
return url, true, nil
|
|
|
|
}
|
|
|
|
return nil, false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Equals returns true if a is value-equal to other. In this case, value equality is determined only by the hash: even
|
|
|
|
// if the contents of two assets come from different sources, they are treated as equal if their hashes match.
|
|
|
|
// Similarly, if the contents of two assets come from the same source but the assets have different hashes, the assets
|
|
|
|
// are not equal.
|
|
|
|
func (a *Asset) Equals(other *Asset) bool {
|
|
|
|
if a == nil {
|
|
|
|
return other == nil
|
|
|
|
} else if other == nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we can't get a hash for both assets, treat them as differing.
|
|
|
|
if err := a.EnsureHash(); err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
if err := other.EnsureHash(); err != nil {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
return a.Hash == other.Hash
|
|
|
|
}
|
|
|
|
|
|
|
|
// Serialize returns a weakly typed map that contains the right signature for serialization purposes.
|
|
|
|
func (a *Asset) Serialize() map[string]interface{} {
|
|
|
|
result := map[string]interface{}{
|
|
|
|
sig.Key: AssetSig,
|
|
|
|
}
|
|
|
|
if a.Hash != "" {
|
|
|
|
result[AssetHashProperty] = a.Hash
|
|
|
|
}
|
|
|
|
if a.Text != "" {
|
|
|
|
result[AssetTextProperty] = a.Text
|
|
|
|
}
|
|
|
|
if a.Path != "" {
|
|
|
|
result[AssetPathProperty] = a.Path
|
|
|
|
}
|
|
|
|
if a.URI != "" {
|
|
|
|
result[AssetURIProperty] = a.URI
|
|
|
|
}
|
|
|
|
return result
|
|
|
|
}
|
|
|
|
|
|
|
|
// DeserializeAsset checks to see if the map contains an asset, using its signature, and if so deserializes it.
|
|
|
|
func Deserialize(obj map[string]interface{}) (*Asset, bool, error) {
|
|
|
|
// If not an asset, return false immediately.
|
|
|
|
if obj[sig.Key] != AssetSig {
|
|
|
|
return &Asset{}, false, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Else, deserialize the possible fields.
|
|
|
|
var hash string
|
|
|
|
if v, has := obj[AssetHashProperty]; has {
|
|
|
|
h, ok := v.(string)
|
|
|
|
if !ok {
|
|
|
|
return &Asset{}, false, fmt.Errorf("unexpected asset hash of type %T", v)
|
|
|
|
}
|
|
|
|
hash = h
|
|
|
|
}
|
|
|
|
var text string
|
|
|
|
if v, has := obj[AssetTextProperty]; has {
|
|
|
|
t, ok := v.(string)
|
|
|
|
if !ok {
|
|
|
|
return &Asset{}, false, fmt.Errorf("unexpected asset text of type %T", v)
|
|
|
|
}
|
|
|
|
text = t
|
|
|
|
}
|
|
|
|
var path string
|
|
|
|
if v, has := obj[AssetPathProperty]; has {
|
|
|
|
p, ok := v.(string)
|
|
|
|
if !ok {
|
|
|
|
return &Asset{}, false, fmt.Errorf("unexpected asset path of type %T", v)
|
|
|
|
}
|
|
|
|
path = p
|
|
|
|
}
|
|
|
|
var uri string
|
|
|
|
if v, has := obj[AssetURIProperty]; has {
|
|
|
|
u, ok := v.(string)
|
|
|
|
if !ok {
|
|
|
|
return &Asset{}, false, fmt.Errorf("unexpected asset URI of type %T", v)
|
|
|
|
}
|
|
|
|
uri = u
|
|
|
|
}
|
|
|
|
|
2024-04-26 19:05:50 +00:00
|
|
|
return &Asset{Sig: AssetSig, Hash: hash, Text: text, Path: path, URI: uri}, true, nil
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// HasContents indicates whether or not an asset's contents can be read.
|
|
|
|
func (a *Asset) HasContents() bool {
|
|
|
|
return a.IsText() || a.IsPath() || a.IsURI()
|
|
|
|
}
|
|
|
|
|
|
|
|
// Bytes returns the contents of the asset as a byte slice.
|
|
|
|
func (a *Asset) Bytes() ([]byte, error) {
|
|
|
|
// If this is a text asset, just return its bytes directly.
|
|
|
|
if text, istext := a.GetText(); istext {
|
|
|
|
return []byte(text), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
blob, err := a.Read()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return io.ReadAll(blob)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Read begins reading an asset.
|
|
|
|
func (a *Asset) Read() (*Blob, error) {
|
2024-05-02 11:32:54 +00:00
|
|
|
wd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return a.ReadWithWD(wd)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ReadWithWD begins reading an asset.
|
|
|
|
func (a *Asset) ReadWithWD(wd string) (*Blob, error) {
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
if a.IsText() {
|
|
|
|
return a.readText()
|
|
|
|
} else if a.IsPath() {
|
2024-05-02 11:32:54 +00:00
|
|
|
return a.readPath(wd)
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
} else if a.IsURI() {
|
|
|
|
return a.readURI()
|
|
|
|
}
|
|
|
|
return nil, errors.New("unrecognized asset type")
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Asset) readText() (*Blob, error) {
|
|
|
|
text, istext := a.GetText()
|
|
|
|
contract.Assertf(istext, "Expected a text-based asset")
|
|
|
|
return NewByteBlob([]byte(text)), nil
|
|
|
|
}
|
|
|
|
|
2024-05-02 11:32:54 +00:00
|
|
|
func (a *Asset) readPath(wd string) (*Blob, error) {
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
path, ispath := a.GetPath()
|
|
|
|
contract.Assertf(ispath, "Expected a path-based asset")
|
|
|
|
|
2024-05-02 11:32:54 +00:00
|
|
|
if !filepath.IsAbs(path) {
|
|
|
|
path = filepath.Join(wd, path)
|
|
|
|
}
|
|
|
|
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
file, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("failed to open asset file '%v': %w", path, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Do a quick check to make sure it's a file, so we can fail gracefully if someone passes a directory.
|
|
|
|
info, err := file.Stat()
|
|
|
|
if err != nil {
|
|
|
|
contract.IgnoreClose(file)
|
|
|
|
return nil, fmt.Errorf("failed to stat asset file '%v': %w", path, err)
|
|
|
|
}
|
|
|
|
if info.IsDir() {
|
|
|
|
contract.IgnoreClose(file)
|
|
|
|
return nil, fmt.Errorf("asset path '%v' is a directory; try using an archive", path)
|
|
|
|
}
|
|
|
|
|
|
|
|
blob := &Blob{
|
|
|
|
rd: file,
|
|
|
|
sz: info.Size(),
|
|
|
|
}
|
|
|
|
return blob, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a *Asset) readURI() (*Blob, error) {
|
|
|
|
url, isURL, err := a.GetURIURL()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
contract.Assertf(isURL, "Expected a URI-based asset")
|
|
|
|
switch s := url.Scheme; s {
|
|
|
|
case "http", "https":
|
|
|
|
resp, err := httputil.GetWithRetry(url.String(), http.DefaultClient)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return NewReadCloserBlob(resp.Body)
|
|
|
|
case "file":
|
|
|
|
contract.Assertf(url.User == nil, "file:// URIs cannot have a user: %v", url)
|
|
|
|
contract.Assertf(url.RawQuery == "", "file:// URIs cannot have a query string: %v", url)
|
|
|
|
contract.Assertf(url.Fragment == "", "file:// URIs cannot have a fragment: %v", url)
|
|
|
|
if url.Host != "" && url.Host != "localhost" {
|
|
|
|
return nil, fmt.Errorf("file:// host '%v' not supported (only localhost)", url.Host)
|
|
|
|
}
|
|
|
|
f, err := os.Open(url.Path)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return NewFileBlob(f)
|
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("Unrecognized or unsupported URI scheme: %v", s)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// EnsureHash computes the SHA256 hash of the asset's contents and stores it on the object.
|
|
|
|
func (a *Asset) EnsureHash() error {
|
|
|
|
if a.Hash == "" {
|
|
|
|
blob, err := a.Read()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer contract.IgnoreClose(blob)
|
|
|
|
|
|
|
|
hash := sha256.New()
|
|
|
|
n, err := io.Copy(hash, blob)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if n != blob.Size() {
|
|
|
|
return fmt.Errorf("incorrect blob size: expected %v, got %v", blob.Size(), n)
|
|
|
|
}
|
|
|
|
a.Hash = hex.EncodeToString(hash.Sum(nil))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-05-02 11:32:54 +00:00
|
|
|
// EnsureHash computes the SHA256 hash of the asset's contents and stores it on the object.
|
|
|
|
func (a *Asset) EnsureHashWithWD(wd string) error {
|
|
|
|
if a.Hash == "" {
|
|
|
|
blob, err := a.ReadWithWD(wd)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer contract.IgnoreClose(blob)
|
|
|
|
|
|
|
|
hash := sha256.New()
|
|
|
|
n, err := io.Copy(hash, blob)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if n != blob.Size() {
|
|
|
|
return fmt.Errorf("incorrect blob size: expected %v, got %v", blob.Size(), n)
|
|
|
|
}
|
|
|
|
a.Hash = hex.EncodeToString(hash.Sum(nil))
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
Move assets and archives to their own package (#15157)
<!---
Thanks so much for your contribution! If this is your first time
contributing, please ensure that you have read the
[CONTRIBUTING](https://github.com/pulumi/pulumi/blob/master/CONTRIBUTING.md)
documentation.
-->
# Description
This PR is motivated by https://github.com/pulumi/pulumi/pull/15145.
`resource.*` should be built on top of `property.Value`,[^1] which means
that `resource`
needs to be able to import `property.Value`, and so `property` cannot
import
`resource`. Since Assets and Archives are both types of properties, they
must be moved out
of `resource`.
[^1]: For example:
https://github.com/pulumi/pulumi/blob/a1d686227cd7e3c70c51bd772450cb0cd57c1479/sdk/go/common/resource/resource_state.go#L35-L36
## Open Question
This PR moves them to their own sub-folders in `resource`. Should
`asset` and `archive`
live somewhere more high level, like `sdk/go/property/{asset,archive}`?
<!--- Please include a summary of the change and which issue is fixed.
Please also include relevant motivation and context. -->
## Checklist
- [ ] I have run `make tidy` to update any new dependencies
- [ ] I have run `make lint` to verify my code passes the lint check
- [ ] I have formatted my code using `gofumpt`
<!--- Please provide details if the checkbox below is to be left
unchecked. -->
- [ ] I have added tests that prove my fix is effective or that my
feature works
<!---
User-facing changes require a CHANGELOG entry.
-->
- [ ] I have run `make changelog` and committed the
`changelog/pending/<file>` documenting my change
<!--
If the change(s) in this PR is a modification of an existing call to the
Pulumi Cloud,
then the service should honor older versions of the CLI where this
change would not exist.
You must then bump the API version in
/pkg/backend/httpstate/client/api.go, as well as add
it to the service.
-->
- [ ] Yes, there are changes in this PR that warrants bumping the Pulumi
Cloud API version
<!-- @Pulumi employees: If yes, you must submit corresponding changes in
the service repo. -->
2024-01-25 20:39:31 +00:00
|
|
|
// Blob is a blob that implements ReadCloser and offers Len functionality.
|
|
|
|
type Blob struct {
|
|
|
|
rd io.ReadCloser // an underlying reader.
|
|
|
|
sz int64 // the size of the blob.
|
|
|
|
}
|
|
|
|
|
|
|
|
func (blob *Blob) Close() error { return blob.rd.Close() }
|
|
|
|
func (blob *Blob) Read(p []byte) (int, error) { return blob.rd.Read(p) }
|
|
|
|
func (blob *Blob) Size() int64 { return blob.sz }
|
|
|
|
|
|
|
|
// NewByteBlob creates a new byte blob.
|
|
|
|
func NewByteBlob(data []byte) *Blob {
|
|
|
|
return &Blob{
|
|
|
|
rd: io.NopCloser(bytes.NewReader(data)),
|
|
|
|
sz: int64(len(data)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewFileBlob creates a new asset blob whose size is known thanks to stat.
|
|
|
|
func NewFileBlob(f *os.File) (*Blob, error) {
|
|
|
|
stat, err := f.Stat()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &Blob{
|
|
|
|
rd: f,
|
|
|
|
sz: stat.Size(),
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewReadCloserBlob turn any old ReadCloser into an Blob, usually by making a copy.
|
|
|
|
func NewReadCloserBlob(r io.ReadCloser) (*Blob, error) {
|
|
|
|
if f, isf := r.(*os.File); isf {
|
|
|
|
// If it's a file, we can "fast path" the asset creation without making a copy.
|
|
|
|
return NewFileBlob(f)
|
|
|
|
}
|
|
|
|
// Otherwise, read it all in, and create a blob out of that.
|
|
|
|
defer contract.IgnoreClose(r)
|
|
|
|
data, err := io.ReadAll(r)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return NewByteBlob(data), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewRawBlob(r io.ReadCloser, size int64) *Blob {
|
|
|
|
return &Blob{rd: r, sz: size}
|
|
|
|
}
|