Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • bazel/rules_curl
1 result
Show changes
Commits on Source (3)
Showing
with 705 additions and 4 deletions
# [1.0.0-alpha.9](https://git.gitlab.arm.com/bazel/rules_curl/compare/v1.0.0-alpha.8...v1.0.0-alpha.9) (2024-06-25)
### Features
- upload manifests rule ([44570b4](https://git.gitlab.arm.com/bazel/rules_curl/commit/44570b494f07c3dd7a04a12e04f621260647c5ea))
# [1.0.0-alpha.8](https://git.gitlab.arm.com/bazel/rules_curl/compare/v1.0.0-alpha.7...v1.0.0-alpha.8) (2024-06-10)
### Bug Fixes
......
module(
name = "rules_curl",
version = "1.0.0-alpha.8",
version = "1.0.0-alpha.9",
bazel_compatibility = [
">=7.0.0",
],
compatibility_level = 1,
)
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "toolchain_utils", version = "1.0.0-beta.9")
bazel_dep(name = "ape", version = "1.0.0-beta.6")
bazel_dep(name = "rules_go", version = "0.48.1")
export = use_extension("@toolchain_utils//toolchain/export:defs.bzl", "toolchain_export")
use_repo(export, "ape-curl")
......
......@@ -9,18 +9,29 @@
"https://bcr.bazel.build/modules/ape/1.0.0-beta.6/source.json": "a2dda258a2985f703b359d4e287863489314078675e77c4afbf57122324d7c8a",
"https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
"https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862",
"https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
"https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917",
"https://bcr.bazel.build/modules/bazel_skylib/1.6.1/source.json": "082ed5f9837901fada8c68c2f3ddc958bb22b6d654f71dd73f3df30d45d4b749",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/download_utils/1.0.0-beta.2/MODULE.bazel": "bced1551849a5d1ca00b985c0d267ab690af840f04c685f2c62f40e92f66fac0",
"https://bcr.bazel.build/modules/download_utils/1.0.0-beta.2/source.json": "0ab7ebbc57f39a7fe96190e01fe9773482bc4e3d465e9cd9b239bb44ad57791d",
"https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8",
"https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350",
"https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a",
"https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0",
"https://bcr.bazel.build/modules/gazelle/0.36.0/source.json": "0823f097b127e0201ae55d85647c94095edfe27db0431a7ae880dcab08dfaa04",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.11.0/source.json": "c73d9ef4268c91bd0c1cd88f1f9dfa08e814b1dbe89b5f594a9f08ba0244d206",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
......@@ -32,12 +43,18 @@
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573",
"https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
"https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8",
"https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270",
"https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd",
"https://bcr.bazel.build/modules/rules_go/0.48.1/MODULE.bazel": "ad27296e268624d7d53043fe5ff88d5486e7a29596336f629b379b83c67e6d8b",
"https://bcr.bazel.build/modules/rules_go/0.48.1/source.json": "83321289aa500090871d8f761d991f0534946414640cce5c18d2df44cff8e082",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/7.6.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362",
......@@ -50,7 +67,8 @@
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/source.json": "d57902c052424dfda0e71646cb12668d39c4620ee0544294d9d941e7d12bc3a9",
"https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f",
"https://bcr.bazel.build/modules/rules_proto/6.0.0/source.json": "de77e10ff0ab16acbf54e6b46eecd37a99c5b290468ea1aee6e95eb1affdaed7",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
"https://bcr.bazel.build/modules/rules_python/0.22.1/source.json": "57226905e783bae7c37c2dd662be078728e48fa28ee4324a7eabcafb5a43d014",
......
......@@ -9,3 +9,57 @@ Add the following to `MODULE.bazel`:
```py
bazel_dep(module_name = "rules_curl", version = "0.0.0")
```
## Providers
### ManifestInfo
Encapsulates the file to upload and its URL template (see [ManifestInfo][manifest_info])
Members:
- **file**: File
- **url**: string
### ManifestsInfo
The dependency set of `ManifestInfo`s
Members:
- **manifests**: depset of `ManifestInfo`s
## Usage
### curl_upload_file
```py
load("@rules_curl//curl/upload/file:defs.bzl", "curl_upload_file")
curl_upload_file(
name = "upload",
src = ":fixture.txt",
dst = "directory/fixture.txt",
url = "https://test.case",
)
```
### curl_upload_manifests
```py
load("@rules_curl//curl/upload/manifests:defs.bzl", "curl_upload_manifests")
curl_upload_manifests(
name = "upload",
srcs = [
":fixture_1",
":fixture_2",
],
url = "https://test.case",
)
```
> Note: `fixture_1` and `fixture_2` have to provide either `ManifestInfo` or `ManifestsInfo`
[manifest_info]: curl/upload/ManifestInfo.bzl
load("@rules_go//go:def.bzl", "go_binary")
go_binary(
name = "template",
srcs = ["template.go"],
pure = "on",
visibility = ["//curl/upload:__subpackages__"],
)
package main
import (
"bytes"
"flag"
"fmt"
"html/template"
"log"
"net/url"
"path/filepath"
"strconv"
"strings"
)
var manifest ManifestInfo = ManifestInfo{
URL: URLInfo{},
File: FileInfo{},
}
type StringInfo string
func (s StringInfo) String() string {
return string(s)
}
func (s *StringInfo) Set(value string) error {
buf := new(bytes.Buffer)
tmpl, err := template.New("templ").Parse(value)
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(buf, manifest)
if err != nil {
log.Fatal(err)
}
*s = StringInfo(buf.String())
return nil
}
type FileInfo struct {
Dirname StringInfo
Stem StringInfo
Extension StringInfo
}
func (f FileInfo) Basename() string {
return f.Stem.String() + "." + f.Extension.String()
}
func (f FileInfo) Path() string {
return f.Dirname.String() + "/" + f.Basename()
}
func (f FileInfo) String() string {
return f.Path()
}
func (f *FileInfo) Set(value string) error {
clean := filepath.Clean(value)
dirname := filepath.Dir(clean)
f.Dirname = StringInfo(dirname)
extension := filepath.Ext(value)
nodot := strings.TrimPrefix(extension, ".")
f.Extension = StringInfo(nodot)
base := filepath.Base(value)
stem := strings.TrimSuffix(base, extension)
f.Stem = StringInfo(stem)
return nil
}
type URLInfo struct {
Username *StringInfo
Password *StringInfo
Host StringInfo
Pathname StringInfo
Protocol StringInfo
}
func (u URLInfo) split() (string, *int) {
host := u.Host.String()
index := strings.LastIndexByte(host, ':')
if index == -1 {
return host, nil
}
hostname := host[:index]
port, err := strconv.Atoi(host[index+1:])
if err != nil {
log.Fatal(err)
}
return hostname, &port
}
func (u URLInfo) Hostname() string {
hostname, _ := u.split()
return hostname
}
func (u URLInfo) Port() *int {
_, port := u.split()
return port
}
func (u URLInfo) Origin() string {
return u.Protocol.String() + "//" + u.Host.String()
}
func (u URLInfo) Auth() (auth string) {
if u.Username != nil {
auth += string(*u.Username)
}
if u.Password != nil {
auth += ":" + string(*u.Password)
}
return
}
func (u URLInfo) Href() (href string) {
href += u.Protocol.String() + "//"
if auth := u.Auth(); auth != "" {
href += auth + "@"
}
href += u.Host.String()
href += u.Pathname.String()
return
}
func (u URLInfo) String() string {
return u.Href()
}
func (u *URLInfo) Set(value string) error {
parsed, err := url.Parse(value)
if err != nil {
return err
}
if username := parsed.User.Username(); username != "" {
info := StringInfo(username)
u.Username = &info
}
if password, set := parsed.User.Password(); set {
info := StringInfo(password)
u.Password = &info
}
u.Host = StringInfo(parsed.Host)
u.Pathname = StringInfo(parsed.Path)
u.Protocol = StringInfo(parsed.Scheme + ":")
return err
}
type ManifestInfo struct {
URL URLInfo
File FileInfo
}
func main() {
flag.Var(&manifest.File, "file", "The file path to use for templating")
flag.Var(&manifest.File.Dirname, "dirname", "The directory for the destination file")
flag.Var(&manifest.File.Stem, "stem", "The basename of the destination file")
flag.Var(&manifest.File.Extension, "extension", "The extension of the destination file")
flag.Var(&manifest.URL, "url", "URL to use for templating")
flag.Var(&manifest.URL.Host, "host", "The domain name of the URL")
flag.Var(&manifest.URL.Protocol, "scheme", "The scheme for the URL")
flag.Func("pathname", "A location in a hierachical structure of the URL", func(s string) error {
buf := new(bytes.Buffer)
if !strings.HasPrefix(s, "/") {
buf.WriteString("/")
}
buf.WriteString(s)
manifest.URL.Pathname.Set(buf.String())
return nil
})
flag.Func("origin", "The origin of the represented URL.", func(s string) error {
index := strings.Index(s, "//")
if index == -1 {
manifest.URL.Protocol = StringInfo(s)
return nil
}
manifest.URL.Host = StringInfo(s[index+2:])
manifest.URL.Protocol = StringInfo(s[:index])
return nil
})
t := flag.String("template", "{{.URL.Href}}/{{.File.Path}}", "The Go template to render")
flag.Parse()
tmpl, err := template.New("url").Parse(*t)
if err != nil {
log.Fatal(err)
}
buf := new(bytes.Buffer)
err = tmpl.Execute(buf, manifest)
if err != nil {
log.Fatal(err)
}
_, err = url.Parse(buf.String())
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", buf.String())
}
load("@bazel_skylib//lib:types.bzl", "types")
visibility("public")
def init(file, url):
"""
Initializes a `CurlUploadManifestInfo` provider.
To be used with `curl_upload_manifests`
Args:
file: The file to upload.
url: A Starlark string template for the URL, which can include:
- {{.URL.Href}}: the provided URL
- {{.URL.Auth}}: the user:password auth
- {{.URL.Origin}}: the origin of the represented URL
- {{.URL.Port}}: the port number of the URL
- {{.URL.Host}}: the hostname followed by the port if not empty
- {{.URL.Hostname}}: the domain name of the URL
- {{.URL.Protocol}}: the protocol scheme of the URL
- {{.URL.Pathname}}: a location in a hierarchical structure
- {{.File.Path}}: the full path of the file
- {{.File.Basename}}: the basename of the file
- {{.File.Dirname}}: the directory of the file
- {{.File.Stem}}: the file name without extension
- {{.File.Extension}}: the extension of the file
Returns:
A mapping of keywords for the `curl_upload_manifest_info` raw constructor.
"""
if type(file) != "File":
fail("`CurlUploadManifestInfo.file` must be a `file`: {}".format(file))
if file.is_directory:
fail("`CurlUploadManifestInfo.file` must not be a directory: {}".format(file))
if not types.is_string(url):
fail("`CurlUploadManifestInfo.url` must be a `str`: {}".format(url))
if url.find(",") != -1:
fail("`CurlUploadManifestInfo.url` must not have comma `,` sign: {}".format(url))
return {
"file": file,
"url": url,
}
CurlUploadManifestInfo, curl_upload_manifest_info = provider(
"A file to upload with cURL.",
fields = ["file", "url"],
init = init,
)
# Provide some convenience imports
ManifestInfo = CurlUploadManifestInfo
manifest_info = curl_upload_manifest_info
Info = CurlUploadManifestInfo
info = curl_upload_manifest_info
load("@bazel_skylib//lib:types.bzl", "types")
visibility("public")
def init(manifests):
"""
Initializes a `CurlUploadManifestsInfo` provider.
To be used with `curl_upload_manifests`
Args:
manifests: The dependency set of `CurlUploadManifestInfo`s
Returns:
A mapping of keywords for the `curl_upload_manifests_info` raw constructor.
"""
if not types.is_depset(manifests):
fail("`CurlUploadManifestsInfo.url` must be a `depset`: {}".format(manifests))
return {
"manifests": manifests,
}
CurlUploadManifestsInfo, curl_upload_manifests_info = provider(
"Files to upload with cURL.",
fields = ["manifests"],
init = init,
)
# Provide some convenience imports
ManifestsInfo = CurlUploadManifestsInfo
manifests_info = curl_upload_manifests_info
Info = CurlUploadManifestsInfo
info = curl_upload_manifests_info
exports_files([
"posix.tmpl.sh",
"nt.tmpl.bat",
])
alias(
name = "script",
actual = select(
{
"@toolchain_utils//toolchain/constraint/os:windows": ":nt.tmpl.bat",
"//conditions:default": ":posix.tmpl.sh",
},
no_match_error = "No script template available for `curl_upload_manifests`",
),
)
sh_binary(
name = "csv",
srcs = ["csv.sh"],
)
#! /usr/bin/env sh
set -eu -o errexit -o nounset
OUT="${1}"
shift
readonly OUT
for ARG in "${@}"; do
printf >>"${OUT}" '%s\n' "${ARG}"
done
load(":rule.bzl", _manifests = "manifests")
visibility("public")
curl_upload_manifests = _manifests
@echo off
# TODO: implement Windows Batch for `curl_upload`
exit /b 121
#! /usr/bin/env sh
# Strict shell
set -o errexit -o nounset
# Runfiles location
rlocation() (
readonly FILEPATH="${1}"
if test -x "${FILEPATH}"; then
printf '%s' "${FILEPATH}"
return
fi
readonly RUNFILES_DIR="${RUNFILES_DIR-${0}.runfiles}"
if test -x "${RUNFILES_DIR}/${FILEPATH#../}"; then
printf '%s' "${RUNFILES_DIR}/${FILEPATH#../}"
return
fi
if test -x "${RUNFILES_DIR}/"*"/${FILEPATH#../}"; then
printf '%s' "${RUNFILES_DIR}/"*"/${FILEPATH#../}"
return
fi
exit 1
)
# Bazel substitutions
CURL="$(rlocation "{{curl}}")"
CSV="$(rlocation "{{csv}}")"
TEMPLATE="$(rlocation "{{template}}")"
RETRY="{{retry}}"
RETRY_DELAY="{{retry_delay}}"
readonly CURL CSV TEMPLATE RETRY RETRY_DELAY
# Uploads a file
upload() {
printf >&2 "Uploading: %s to %s\n" "${1}" "${2}"
# Do the upload
"${CURL}" \
--netrc \
--location \
--progress-bar \
--retry "${RETRY}" \
--retry-delay "${RETRY_DELAY}" \
--upload-file "$(rlocation "${1}")" \
"${2}"
}
while IFS=, read -r SRC TMPL URL; do
DST=$(
"${TEMPLATE}" \
--url "${URL}" \
--template "${TMPL}" \
--file "${SRC}" \
${@}
)
upload "${SRC}" "${DST}"
done <"${CSV}"
load("//curl/upload:ManifestInfo.bzl", "ManifestInfo")
load("//curl/upload:ManifestsInfo.bzl", "ManifestsInfo")
visibility("//curl/...")
DOC = """Upload bunch of files to a URL endpoint with cURL.
The `srcs` must provide `ManifestInfo` or `ManifestsInfo`.
```py
file(
name = "upload_files",
srcs = [
":data",
],
url = "https://host.name.to.upload",
)
```
"""
ATTRS = {
"srcs": attr.label_list(
doc = "Files to be uploaded.",
mandatory = True,
providers = [
[ManifestInfo],
[ManifestsInfo],
],
allow_files = False,
),
"url": attr.string(
doc = "URL endpoint for files to upload.",
mandatory = True,
),
"retry": attr.int(
doc = "The number of retry attempts for every file.",
default = 3,
),
"retry_delay": attr.int(
doc = "The seconds to wait before attempting an upload retry.",
default = 1,
),
"_script": attr.label(
doc = "The template that is expanded into the upload binary.",
default = ":script",
allow_single_file = True,
),
"_template": attr.label(
default = "//curl/template:template",
cfg = "exec",
allow_single_file = True,
executable = True,
),
"_csv": attr.label(
doc = "CSV tool",
default = ":csv",
cfg = "exec",
executable = True,
),
}
def implementation(ctx):
curl = ctx.toolchains["//curl/toolchain/curl:type"]
csv = ctx.actions.declare_file("upload.csv")
manifests = depset(
direct = [src[ManifestInfo] for src in ctx.attr.srcs if ManifestInfo in src],
transitive = [src[ManifestsInfo].manifests for src in ctx.attr.srcs if ManifestsInfo in src],
)
href = ctx.attr.url.rstrip("/").replace(",", "%2C")
def _to_string(m):
# SRC,URL_TEMPL,URL
return "{},{},{}".format(m.file.short_path, m.url, href)
args = ctx.actions.args()
args.add_all(manifests, map_each = _to_string, allow_closure = True)
ctx.actions.run(
outputs = [csv],
arguments = [csv.path, args],
executable = ctx.executable._csv,
)
executable = ctx.actions.declare_file("{}.sh".format(ctx.label.name))
substitutions = ctx.actions.template_dict()
substitutions.add("{{curl}}", str(curl.executable.short_path))
substitutions.add("{{retry}}", str(ctx.attr.retry))
substitutions.add("{{retry_delay}}", str(ctx.attr.retry_delay))
substitutions.add("{{csv}}", str(csv.short_path))
substitutions.add("{{template}}", str(ctx.executable._template.short_path))
ctx.actions.expand_template(
template = ctx.file._script,
output = executable,
computed_substitutions = substitutions,
is_executable = True,
)
files = depset([executable])
runfiles = ctx.runfiles([curl.executable, csv, ctx.executable._template] + [m.file for m in manifests.to_list()])
runfiles = runfiles.merge(curl.default.default_runfiles)
runfiles = runfiles.merge(ctx.attr._template.default_runfiles)
return DefaultInfo(
executable = executable,
files = files,
runfiles = runfiles,
)
curl_upload_manifests = rule(
doc = DOC,
attrs = ATTRS,
implementation = implementation,
toolchains = ["//curl/toolchain/curl:type"],
executable = True,
)
manifests = curl_upload_manifests
......@@ -7,6 +7,8 @@ module(
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "toolchain_utils", version = "1.0.0-beta.9")
bazel_dep(name = "rules_diff", version = "1.0.0-beta.3")
bazel_dep(name = "hermetic_cc_toolchain", version = "3.1.0")
bazel_dep(name = "rules_curl")
local_path_override(
module_name = "rules_curl",
......
......@@ -9,9 +9,14 @@
"https://bcr.bazel.build/modules/ape/1.0.0-beta.6/source.json": "a2dda258a2985f703b359d4e287863489314078675e77c4afbf57122324d7c8a",
"https://bcr.bazel.build/modules/apple_support/1.5.0/MODULE.bazel": "50341a62efbc483e8a2a6aec30994a58749bd7b885e18dd96aa8c33031e558ef",
"https://bcr.bazel.build/modules/apple_support/1.5.0/source.json": "eb98a7627c0bc486b57f598ad8da50f6625d974c8f723e9ea71bd39f709c9862",
"https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b",
"https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8",
"https://bcr.bazel.build/modules/bazel_features/1.11.0/source.json": "c9320aa53cd1c441d24bd6b716da087ad7e4ff0d9742a9884587596edfe53015",
"https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7",
"https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a",
"https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686",
"https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a",
"https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5",
"https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651",
......@@ -22,6 +27,11 @@
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/download_utils/1.0.0-beta.2/MODULE.bazel": "bced1551849a5d1ca00b985c0d267ab690af840f04c685f2c62f40e92f66fac0",
"https://bcr.bazel.build/modules/download_utils/1.0.0-beta.2/source.json": "0ab7ebbc57f39a7fe96190e01fe9773482bc4e3d465e9cd9b239bb44ad57791d",
"https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8",
"https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350",
"https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a",
"https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0",
"https://bcr.bazel.build/modules/gazelle/0.36.0/source.json": "0823f097b127e0201ae55d85647c94095edfe27db0431a7ae880dcab08dfaa04",
"https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
"https://bcr.bazel.build/modules/googletest/1.11.0/source.json": "c73d9ef4268c91bd0c1cd88f1f9dfa08e814b1dbe89b5f594a9f08ba0244d206",
"https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee",
......@@ -33,12 +43,20 @@
"https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7",
"https://bcr.bazel.build/modules/protobuf/21.7/source.json": "bbe500720421e582ff2d18b0802464205138c06056f443184de39fbb8187b09b",
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573",
"https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c",
"https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5",
"https://bcr.bazel.build/modules/rules_cc/0.0.9/source.json": "1f1ba6fea244b616de4a554a0f4983c91a9301640c8fe0dd1d410254115c8430",
"https://bcr.bazel.build/modules/rules_diff/1.0.0-beta.3/MODULE.bazel": "4bcae1c5e3c7fa1169f9940f548f7b8b3316944b4367771b168f925b7a9ee74e",
"https://bcr.bazel.build/modules/rules_diff/1.0.0-beta.3/source.json": "b5db3fcd469061f2051188da97345162f294fc59e7fdf477beb306dbe950566a",
"https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8",
"https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270",
"https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd",
"https://bcr.bazel.build/modules/rules_go/0.48.1/MODULE.bazel": "ad27296e268624d7d53043fe5ff88d5486e7a29596336f629b379b83c67e6d8b",
"https://bcr.bazel.build/modules/rules_go/0.48.1/source.json": "83321289aa500090871d8f761d991f0534946414640cce5c18d2df44cff8e082",
"https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74",
"https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe",
"https://bcr.bazel.build/modules/rules_java/7.6.1/source.json": "8f3f3076554e1558e8e468b2232991c510ecbcbed9e6f8c06ac31c93bcf38362",
......@@ -51,7 +69,8 @@
"https://bcr.bazel.build/modules/rules_pkg/0.7.0/source.json": "c2557066e0c0342223ba592510ad3d812d4963b9024831f7f66fd0584dd8c66c",
"https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7",
"https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/source.json": "d57902c052424dfda0e71646cb12668d39c4620ee0544294d9d941e7d12bc3a9",
"https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f",
"https://bcr.bazel.build/modules/rules_proto/6.0.0/source.json": "de77e10ff0ab16acbf54e6b46eecd37a99c5b290468ea1aee6e95eb1affdaed7",
"https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f",
"https://bcr.bazel.build/modules/rules_python/0.22.1/MODULE.bazel": "26114f0c0b5e93018c0c066d6673f1a2c3737c7e90af95eff30cfee38d0bbac7",
"https://bcr.bazel.build/modules/rules_python/0.22.1/source.json": "57226905e783bae7c37c2dd662be078728e48fa28ee4324a7eabcafb5a43d014",
......@@ -117,7 +136,7 @@
"@@toolchain_utils~//toolchain/export:defs.bzl%toolchain_export": {
"general": {
"bzlTransitiveDigest": "n2fd+/jiAv/nvvi2WUR+VQxI3aTZGNuhuX/NuFhw5fM=",
"usagesDigest": "A2BbbNuBP0QFNqjCVowoaEOrolUDkTAis6lyamxEXLE=",
"usagesDigest": "OT9pdXtWdZUfYUSpReUZ6+fci56uJ5AVYR22QqnoBYI=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
......@@ -374,6 +393,13 @@
"target": "@@ape~~_repo_rules~seq//:seq"
}
},
"diff": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
"attributes": {
"target": "@@toolchain_utils~~toolchain_export~ape-diff//:ape-diff"
}
},
"ape-printenv": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
......@@ -549,6 +575,13 @@
"target": "@@ape~~_repo_rules~qjs//:qjs"
}
},
"cmp": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
"attributes": {
"target": "@@toolchain_utils~~toolchain_export~ape-cmp//:ape-cmp"
}
},
"ape-df": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
......@@ -738,6 +771,20 @@
"target": "@@ape~~_repo_rules~nohup//:nohup"
}
},
"sdiff": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
"attributes": {
"target": "@@toolchain_utils~~toolchain_export~ape-sdiff//:ape-sdiff"
}
},
"diff3": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
"attributes": {
"target": "@@toolchain_utils~~toolchain_export~ape-diff3//:ape-diff3"
}
},
"ape-basename": {
"bzlFile": "@@toolchain_utils~//toolchain/export/symlink:repository.bzl",
"ruleClassName": "symlink",
......
load("@rules_curl//curl/upload:ManifestInfo.bzl", "ManifestInfo")
DOC = """Mock rule with output `ManifestInfo` provider.
```py
mock_manifest(
name = "mock_file",
)
```
"""
def _impl(ctx):
out = ctx.actions.declare_file("{}.out".format(ctx.attr.name))
ctx.actions.write(out, "hello test", is_executable = False)
return [
DefaultInfo(
files = depset([out]),
),
ManifestInfo(
file = out,
url = "{{.URL.Href}}/{{.File.Path}}",
),
]
mock_manifest = rule(
doc = DOC,
implementation = _impl,
provides = [
ManifestInfo,
],
)