feat: support location expansion in tar (#774)

diff --git a/docs/tar.md b/docs/tar.md
index 8a08485..4b0c59a 100644
--- a/docs/tar.md
+++ b/docs/tar.md
@@ -100,7 +100,7 @@
 ## tar
 
 <pre>
-tar(<a href="#tar-name">name</a>, <a href="#tar-mtree">mtree</a>, <a href="#tar-kwargs">kwargs</a>)
+tar(<a href="#tar-name">name</a>, <a href="#tar-mtree">mtree</a>, <a href="#tar-stamp">stamp</a>, <a href="#tar-kwargs">kwargs</a>)
 </pre>
 
 Wrapper macro around [`tar_rule`](#tar_rule).
@@ -136,7 +136,8 @@
 | Name  | Description | Default Value |
 | :------------- | :------------- | :------------- |
 | <a id="tar-name"></a>name |  name of resulting <code>tar_rule</code>   |  none |
-| <a id="tar-mtree"></a>mtree |  "auto", or an array of specification lines, or a label of a file that contains the lines.   |  <code>"auto"</code> |
+| <a id="tar-mtree"></a>mtree |  "auto", or an array of specification lines, or a label of a file that contains the lines. Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables) and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution.   |  <code>"auto"</code> |
+| <a id="tar-stamp"></a>stamp |  should mtree attribute be stamped   |  <code>0</code> |
 | <a id="tar-kwargs"></a>kwargs |  additional named parameters to pass to <code>tar_rule</code>   |  none |
 
 
diff --git a/lib/BUILD.bazel b/lib/BUILD.bazel
index 0a56285..442f5d8 100644
--- a/lib/BUILD.bazel
+++ b/lib/BUILD.bazel
@@ -104,10 +104,10 @@
     name = "tar",
     srcs = ["tar.bzl"],
     deps = [
+        "//lib:expand_template",
         "//lib:utils",
         "//lib/private:tar",
         "@bazel_skylib//lib:types",
-        "@bazel_skylib//rules:write_file",
     ],
 )
 
diff --git a/lib/tar.bzl b/lib/tar.bzl
index f62fef6..3dd7a65 100644
--- a/lib/tar.bzl
+++ b/lib/tar.bzl
@@ -50,7 +50,7 @@
 """
 
 load("@bazel_skylib//lib:types.bzl", "types")
-load("@bazel_skylib//rules:write_file.bzl", "write_file")
+load("//lib:expand_template.bzl", "expand_template")
 load("//lib:utils.bzl", "propagate_common_rule_attributes")
 load("//lib/private:tar.bzl", _tar = "tar", _tar_lib = "tar_lib")
 
@@ -64,7 +64,7 @@
 
 tar_lib = _tar_lib
 
-def tar(name, mtree = "auto", **kwargs):
+def tar(name, mtree = "auto", stamp = 0, **kwargs):
     """Wrapper macro around [`tar_rule`](#tar_rule).
 
     ### Options for mtree
@@ -94,6 +94,9 @@
     Args:
         name: name of resulting `tar_rule`
         mtree: "auto", or an array of specification lines, or a label of a file that contains the lines.
+            Subject to [$(location)](https://bazel.build/reference/be/make-variables#predefined_label_variables)
+            and ["Make variable"](https://bazel.build/reference/be/make-variables) substitution.
+        stamp: should mtree attribute be stamped
         **kwargs: additional named parameters to pass to `tar_rule`
     """
     mtree_target = "_{}.mtree".format(name)
@@ -105,12 +108,18 @@
             **propagate_common_rule_attributes(kwargs)
         )
     elif types.is_list(mtree):
-        write_file(
+        expand_template(
             name = mtree_target,
             out = "{}.txt".format(mtree_target),
+            data = kwargs["srcs"],
             # Ensure there's a trailing newline, as bsdtar will ignore a last line without one
-            content = mtree + [""],
-            newline = "unix",
+            template = ["#mtree", "{content}", ""],
+            substitutions = {
+                # expand_template only expands strings in "substitions" dict. Here
+                # we expand mtree and then replace the template with expanded mtree.
+                "{content}": "\n".join(mtree),
+            },
+            stamp = stamp,
             **propagate_common_rule_attributes(kwargs)
         )
     else:
diff --git a/lib/tests/tar/BUILD.bazel b/lib/tests/tar/BUILD.bazel
index 010e8e9..0036d30 100644
--- a/lib/tests/tar/BUILD.bazel
+++ b/lib/tests/tar/BUILD.bazel
@@ -310,3 +310,21 @@
         "LICENSE",
     ],
 )
+
+# Case 10: Can reference generated files
+tar(
+    name = "tar_location_expansion",
+    srcs = ["@bazel_skylib//:LICENSE"],
+    out = "10.tar",
+    mtree = [
+        "a uid=0 gid=0 time=1672560000 mode=0755 type=file content=$(location @bazel_skylib//:LICENSE)",
+    ],
+)
+
+assert_tar_listing(
+    name = "test_tar_location_expansion",
+    actual = "tar_location_expansion",
+    expected = [
+        "-rwxr-xr-x  0 0      0       11358 Jan  1  2023 a",
+    ],
+)