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_tar
  • alexeagle/rules_tar
2 results
Show changes
Commits on Source (4)
Showing
with 2052 additions and 7 deletions
# [1.0.0-beta.3](https://git.gitlab.arm.com/bazel/rules_tar/compare/v1.0.0-beta.2...v1.0.0-beta.3) (2024-09-05)
### Bug Fixes
- **concatenate:** log header read error ([0aa6a7c](https://git.gitlab.arm.com/bazel/rules_tar/commit/0aa6a7c7a041eeb7d086abd1e37913b0f9b3bc21))
### Features
- add `tar_filter` rule ([271a34c](https://git.gitlab.arm.com/bazel/rules_tar/commit/271a34cb528fcfa7ae9cd308bd4fa2914bfe4ec9))
# [1.0.0-beta.2](https://git.gitlab.arm.com/bazel/rules_tar/compare/v1.0.0-beta.1...v1.0.0-beta.2) (2024-08-30)
### Bug Fixes
......
module(
name = "rules_tar",
version = "1.0.0-beta.2",
version = "1.0.0-beta.3",
bazel_compatibility = [
">=7.0.0",
],
......@@ -16,6 +16,7 @@ bazel_dep(name = "toolchain_utils", version = "1.0.0-beta.12")
bazel_dep(name = "ape", version = "1.0.0-beta.12")
bazel_dep(name = "rules_go", version = "0.49.0")
bazel_dep(name = "platforms", version = "0.0.10")
bazel_dep(name = "gazelle", version = "0.38.0")
bazel_dep(name = "hermetic_cc_toolchain", version = "3.1.0", dev_dependency = True)
......@@ -34,7 +35,14 @@ resolved = use_repo_rule("@toolchain_utils//toolchain/resolved:defs.bzl", "toolc
name = "resolved-{}".format(toolchain),
toolchain_type = "//tar/toolchain/{}:type".format(toolchain),
)
for toolchain in ("tar", "concatenate")
for toolchain in ("tar", "concatenate", "filter")
]
register_toolchains("//tar/toolchain/...")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(
go_deps,
"com_github_bmatcuk_doublestar_v4",
)
This diff is collapsed.
......@@ -36,7 +36,8 @@
"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/gazelle/0.38.0/MODULE.bazel": "51bb3ca009bc9320492894aece6ba5f50aae68a39fff2567844b77fc12e2d0a5",
"https://bcr.bazel.build/modules/gazelle/0.38.0/source.json": "7fedf9b531bcbbe90b009e4d3aef478a2defb8b8a6e31e931445231e425fc37c",
"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/hermetic_cc_toolchain/3.1.0/MODULE.bazel": "ea4b3a25a9417a7db57a8a2f9ebdee91d679823c6274b482b817ed128d81c594",
......@@ -69,6 +70,7 @@
"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.47.0/MODULE.bazel": "e425890d2a4d668abc0f59d8388b70bf63ad025edec76a385c35d85882519417",
"https://bcr.bazel.build/modules/rules_go/0.49.0/MODULE.bazel": "61cfc1ba17123356d1b12b6c50f6e0162b2cc7fd6f51753c12471e973a0f72a5",
"https://bcr.bazel.build/modules/rules_go/0.49.0/source.json": "ab2261ea5e29d29a41c8e5c67896f946ab7855b786d28fe25d74987b84e5e85d",
"https://bcr.bazel.build/modules/rules_gzip/1.0.0-beta.1/MODULE.bazel": "4bc3bb009698531db230bb85a290355e7805d0cf7b5e8b60f62ee8ac65af0405",
......
load("@rules_diff//diff/directory/test:defs.bzl", "diff_directory_test")
load("@rules_tar//tar/unpack:defs.bzl", "tar_unpack")
load("@rules_tar//tar/filter:defs.bzl", "tar_filter")
tar_filter(
name = "filtered.tar",
src = "//fixture:fixture.tar",
patterns = ["fixture/*.txt"],
)
tar_unpack(
name = "unpack",
src = ":filtered.tar",
)
diff_directory_test(
name = "diff",
size = "small",
a = "//fixture/directory:txt",
b = ":unpack",
)
load("@rules_diff//diff/directory/test:defs.bzl", "diff_directory_test")
load("@rules_tar//tar/unpack:defs.bzl", "tar_unpack")
load("@rules_tar//tar/filter:defs.bzl", "tar_filter")
tar_filter(
name = "filtered.tar.bz2",
src = "//fixture:fixture.tar.bz2",
patterns = ["fixture/*.txt"],
)
tar_unpack(
name = "unpack",
src = ":filtered.tar.bz2",
)
diff_directory_test(
name = "diff",
size = "small",
a = "//fixture/directory:txt",
b = ":unpack",
)
load("@rules_diff//diff/directory/test:defs.bzl", "diff_directory_test")
load("@rules_tar//tar/unpack:defs.bzl", "tar_unpack")
load("@rules_tar//tar/filter:defs.bzl", "tar_filter")
tar_filter(
name = "filtered.tar.gz",
src = "//fixture:fixture.tar.gz",
patterns = ["fixture/*.txt"],
)
tar_unpack(
name = "unpack",
src = ":filtered.tar.gz",
)
diff_directory_test(
name = "diff",
size = "small",
a = "//fixture/directory:txt",
b = ":unpack",
)
load("@rules_diff//diff/directory/test:defs.bzl", "diff_directory_test")
load("@rules_tar//tar/unpack:defs.bzl", "tar_unpack")
load("@rules_tar//tar/filter:defs.bzl", "tar_filter")
tar_filter(
name = "filtered.tar.xz",
src = "//fixture:fixture.tar.xz",
patterns = ["fixture/*.txt"],
)
tar_unpack(
name = "unpack",
src = ":filtered.tar.xz",
)
diff_directory_test(
name = "diff",
size = "small",
a = "//fixture/directory:txt",
b = ":unpack",
)
load("@rules_diff//diff/directory/test:defs.bzl", "diff_directory_test")
load("@rules_tar//tar/unpack:defs.bzl", "tar_unpack")
load("@rules_tar//tar/filter:defs.bzl", "tar_filter")
tar_filter(
name = "filtered.tar.zst",
src = "//fixture:fixture.tar.zst",
patterns = ["fixture/*.txt"],
)
tar_unpack(
name = "unpack",
src = ":filtered.tar.zst",
)
diff_directory_test(
name = "diff",
size = "small",
a = "//fixture/directory:txt",
b = ":unpack",
)
......@@ -30,3 +30,12 @@ fixture_directory(
],
visibility = ["//:__subpackages__"],
)
fixture_directory(
name = "txt",
srcs = [
"//fixture:goodbye-world.txt",
"//fixture:hello-world.txt",
],
visibility = ["//:__subpackages__"],
)
load("@rules_go//go:def.bzl", "go_binary")
load("@rules_go//go:def.bzl", "go_binary", "go_library")
alias(
name = "template",
......@@ -10,7 +10,14 @@ alias(
go_binary(
name = "concatenate",
srcs = ["main.go"],
embed = [":concatenate_lib"],
pure = "on",
visibility = ["//visibility:public"],
)
go_library(
name = "concatenate_lib",
srcs = ["main.go"],
importpath = "gitlab.arm.com/bazel/rules_tar/v1/tar/concatenate",
visibility = ["//visibility:private"],
)
......@@ -275,6 +275,9 @@ func main() {
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
if _, exists := paths[h.Name]; exists {
switch flags.Duplicate {
case DuplicateError:
......
......@@ -12,7 +12,7 @@ BZIP2="{{bzip2}}"
XZ="{{xz}}"
ZSTD="{{zstd}}"
COMPRESS="{{compress}}"
readonly CONCATENATE GZIP BZIP2 XZ ZSTD COMPRESS
readonly CONCATENATE CAT GZIP BZIP2 XZ ZSTD COMPRESS
# Parse the output
test "--output" = "${1}"
......
load("@rules_go//go:def.bzl", "go_binary", "go_library")
alias(
name = "template",
actual = select({
"//conditions:default": ":posix.tmpl.sh",
}),
visibility = ["//:__subpackages__"],
)
go_binary(
name = "filter",
embed = [":filter_lib"],
pure = "on",
visibility = ["//visibility:public"],
)
go_library(
name = "filter_lib",
srcs = ["main.go"],
importpath = "gitlab.arm.com/bazel/rules_tar/v1/tar/filter",
visibility = ["//visibility:private"],
deps = ["@com_github_bmatcuk_doublestar_v4//:go_default_library"],
)
load(":rule.bzl", _filter = "filter")
visibility("public")
tar_filter = _filter
package main
import (
"archive/tar"
"bufio"
"flag"
"io"
"log"
"os"
"path"
"syscall"
"strings"
"fmt"
"github.com/bmatcuk/doublestar/v4"
)
type Input interface {
Read(b []byte) (int, error)
Peek(n int) ([]byte, error)
Discard(n int) (int, error)
Close() error
}
type FileInput struct {
f *os.File
b *bufio.Reader
}
func NewFileInput(f *os.File) FileInput {
return FileInput{f, bufio.NewReader(f)}
}
func (i FileInput) Read(b []byte) (int, error) {
return i.b.Read(b)
}
func (i FileInput) Peek(n int) ([]byte, error) {
return i.b.Peek(n)
}
func (i FileInput) Discard(n int) (int, error) {
return i.b.Discard(n)
}
func (i FileInput) Close() error {
return i.f.Close()
}
type StdInput struct {
b *bufio.Reader
}
func NewStdInput() StdInput {
return StdInput{bufio.NewReader(os.Stdin)}
}
func (i StdInput) Read(b []byte) (int, error) {
return i.b.Read(b)
}
func (i StdInput) Peek(n int) ([]byte, error) {
return i.b.Peek(n)
}
func (i StdInput) Discard(n int) (int, error) {
return i.b.Discard(n)
}
func (i StdInput) Close() error {
return nil
}
func open(v string) (Input, error) {
if v == "-" {
return NewStdInput(), nil
}
f, err := os.Open(v)
switch e := err.(type) {
case *os.PathError:
if e.Err == syscall.ENOENT {
if bwd, ok := os.LookupEnv("BUILD_WORKING_DIRECTORY"); ok {
f, err = os.Open(path.Join(bwd, v))
}
}
}
if err != nil {
return nil, err
}
return NewFileInput(f), nil
}
type Output interface {
Write(b []byte) (int, error)
Close() error
}
type FileOutput struct {
f *os.File
}
func NewFileOutput(f *os.File) FileOutput {
return FileOutput{f}
}
func (i FileOutput) Write(b []byte) (int, error) {
return i.f.Write(b)
}
func (i FileOutput) Close() error {
return i.f.Close()
}
type StdOutput struct{}
func NewStdOutput() StdOutput {
return StdOutput{}
}
func (i StdOutput) Write(b []byte) (int, error) {
return os.Stdout.Write(b)
}
func (i StdOutput) Close() error {
return nil
}
type OutputFlag struct {
o Output
}
func NewStdOutputFlag() OutputFlag {
return OutputFlag{NewStdOutput()}
}
func (f OutputFlag) Write(b []byte) (int, error) {
return f.o.Write(b)
}
func (f OutputFlag) Close() error {
return f.o.Close()
}
func (f *OutputFlag) Set(value string) error {
if value == "-" {
f.o = NewStdOutput()
}
if !path.IsAbs(value) {
if bwd, ok := os.LookupEnv("BUILD_WORKING_DIRECTORY"); ok {
value = path.Join(bwd, value)
}
}
x, err := os.OpenFile(value, os.O_WRONLY|os.O_CREATE, 0644)
if err != nil {
return err
}
f.o = NewFileOutput(x)
return nil
}
func (f OutputFlag) String() string {
switch f.o.(type) {
case *StdOutput:
return "-"
case *FileOutput:
return "<file>"
}
return "<unknown>"
}
type PatternsFlag struct {
patterns []string
}
func NewPatternsFlag() PatternsFlag {
return PatternsFlag{}
}
func (p *PatternsFlag) Set(value string) error {
if !doublestar.ValidatePattern(strings.TrimPrefix(value, "!")) {
return fmt.Errorf("Invalid pattern: %s", value)
}
p.patterns = append(p.patterns, value)
return nil
}
func (p PatternsFlag) String() string {
return strings.Join(p.patterns, ",")
}
func (p PatternsFlag) Match(name string) (bool, error) {
for _, pattern := range p.patterns {
after, found := strings.CutPrefix(pattern, "!")
match, err := doublestar.Match(after, name)
if err != nil {
return match, err
}
if match {
return !found, err
}
}
return false, nil
}
type Flags struct {
Output OutputFlag
Patterns PatternsFlag
}
func main() {
flags := Flags{NewStdOutputFlag(), NewPatternsFlag()}
flag.Var(&flags.Output, "output", "Output location for filtered `tar`.")
flag.Var(&flags.Patterns, "pattern", "A glob pattern to filter archive members.")
flag.Parse()
w := tar.NewWriter(flags.Output)
defer w.Close()
args := flag.Args()
switch len(args) {
case 0:
args = []string{"-"}
default:
log.Fatalf("Invalid number of archives: %s", args)
case 1:
}
for _, archive := range args {
f, err := open(archive)
if err != nil {
log.Fatal(err)
}
defer f.Close()
r := tar.NewReader(f)
for {
h, err := r.Next()
if err == io.EOF {
break
}
match, err := flags.Patterns.Match(h.Name)
if err != nil {
log.Fatal(err)
}
if !match {
continue
}
if err := w.WriteHeader(h); err != nil {
log.Fatal(err)
}
if _, err := io.Copy(w, r); err != nil {
log.Fatal(err)
}
}
if err := f.Close(); err != nil {
log.Fatal(err)
}
}
if err := w.Close(); err != nil {
log.Fatal(err)
}
}
#! /usr/bin/env bash
# Strict Shell
set -o errexit
set -o nounset
set -o pipefail
# Bazel replacements
FILTER="{{filter}}"
CAT="{{cat}}"
GZIP="{{gzip}}"
BZIP2="{{bzip2}}"
XZ="{{xz}}"
ZSTD="{{zstd}}"
COMPRESS="{{compress}}"
readonly FILTER CAT GZIP BZIP2 XZ ZSTD COMPRESS
# Parse the output
test "--output" = "${1}"
shift
OUTPUT="${1}"
readonly OUTPUT
shift
# Parse the patterns
declare -a ARGS
while test $# != 0; do
case "${1}" in
"--pattern="*)
ARGS+=("${1}")
;;
"--pattern")
ARGS+=("${1}" "${2}")
shift
;;
*)
break
;;
esac
shift
done
# Concatenate
{
for TAR in "${@}"; do
case "${TAR}" in
*".tar")
"${CAT}" "${TAR}"
;;
*".tar.gz")
"${GZIP}" -fcd "${TAR}"
;;
*".tar.bz2")
"${BZIP2}" -fcd "${TAR}"
;;
*".tar.xz")
"${XZ}" -fcd "${TAR}"
;;
*".tar.zst")
"${ZSTD}" -fcd "${TAR}"
;;
*)
echo >&2 "Unsupported: ${TAR}"
exit 2
;;
esac
done
} |
"${FILTER}" "${ARGS[@]}" |
"${COMPRESS}" >"${OUTPUT}"