We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
JVM resource jar creation is broken on Mac by variation in `touch` command.
BSD touch uses `-t` to set the timestamp whereas GNU touch uses `-d`. We use / assume the GNU binary as noted here: https://github.com/pantsbuild/pants/pull/16950#discussion_r1157196330

As discovered here: https://pantsbuild.slack.com/archives/C046T6T9U/p1680604327733559?thread_ts=1680604327.733559&cid=C046T6T9U

Where the error looks like:
```
 12:24:56.74 [ERROR] 1 Exception encountered:
 
 Engine traceback:
   in select
   in pants.core.goals.check.check
   in pants.backend.scala.goals.check.scalac_check (scalac)
   in pants.backend.scala.compile.scalac.compile_scala_source
   in pants.jvm.compile.compile_classpath_entries
   in pants.jvm.resources.assemble_resources_jar
   in pants.engine.process.fallible_to_exec_result_or_raise
 Traceback (most recent call last):
   File "/Users/jbenito/.cache/pants/setup/bootstrap-Darwin-x86_64/pants.1Nnv7r/install/lib/python3.9/site-packages/pants/engine/process.py", line 275, in fallible_to_exec_result_or_raise
     raise ProcessExecutionFailure(
 pants.engine.process.ProcessExecutionFailure: Process 'Build resources JAR for sdk/transport-security-web-lib/src/test/resources:resources' failed with exit code 1.
 stdout:
 
 stderr:
 /usr/bin/touch: illegal option -- d
 usage:
 touch [-A [-][[hh]mm]SS] [-acfhm] [-r file] [-t [[CC]YY]MMDDhhmm[.SS]] file ...
```

It appears #16950 was cherry picked back to 2.13.1 and 2.14.0; so Pants has been broken for JVM resource jars since 2.13.1.



--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/python/pants/jvm/resources.py`
Content:
```
1 # Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).
2 # Licensed under the Apache License, Version 2.0 (see LICENSE).
3 
4 import itertools
5 import logging
6 import shlex
7 from itertools import chain
8 from pathlib import Path
9 
10 from pants.core.target_types import ResourcesFieldSet, ResourcesGeneratorFieldSet
11 from pants.core.util_rules import stripped_source_files
12 from pants.core.util_rules.source_files import SourceFilesRequest
13 from pants.core.util_rules.stripped_source_files import StrippedSourceFiles
14 from pants.core.util_rules.system_binaries import BashBinary, TouchBinary, ZipBinary
15 from pants.engine.fs import Digest, MergeDigests
16 from pants.engine.internals.selectors import MultiGet
17 from pants.engine.process import Process, ProcessResult
18 from pants.engine.rules import Get, collect_rules, rule
19 from pants.engine.target import SourcesField
20 from pants.engine.unions import UnionRule
21 from pants.jvm import compile
22 from pants.jvm.compile import (
23     ClasspathDependenciesRequest,
24     ClasspathEntry,
25     ClasspathEntryRequest,
26     ClasspathEntryRequests,
27     CompileResult,
28     FallibleClasspathEntries,
29     FallibleClasspathEntry,
30 )
31 from pants.jvm.subsystems import JvmSubsystem
32 from pants.util.logging import LogLevel
33 
34 logger = logging.getLogger(__name__)
35 
36 
37 class JvmResourcesRequest(ClasspathEntryRequest):
38     field_sets = (
39         ResourcesFieldSet,
40         ResourcesGeneratorFieldSet,
41     )
42 
43 
44 @rule(desc="Assemble resources")
45 async def assemble_resources_jar(
46     zip: ZipBinary,
47     bash: BashBinary,
48     touch: TouchBinary,
49     jvm: JvmSubsystem,
50     request: JvmResourcesRequest,
51 ) -> FallibleClasspathEntry:
52     # Request the component's direct dependency classpath, and additionally any prerequisite.
53     # Filter out any dependencies that are generated by our current target so that each resource
54     # only appears in a single input JAR.
55     # NOTE: Generated dependencies will have the same dependencies as the current target, so we
56     # don't need to inspect those dependencies.
57     optional_prereq_request = [*((request.prerequisite,) if request.prerequisite else ())]
58     fallibles = await MultiGet(
59         Get(FallibleClasspathEntries, ClasspathEntryRequests(optional_prereq_request)),
60         Get(FallibleClasspathEntries, ClasspathDependenciesRequest(request, ignore_generated=True)),
61     )
62     direct_dependency_classpath_entries = FallibleClasspathEntries(
63         itertools.chain(*fallibles)
64     ).if_all_succeeded()
65 
66     if direct_dependency_classpath_entries is None:
67         return FallibleClasspathEntry(
68             description=str(request.component),
69             result=CompileResult.DEPENDENCY_FAILED,
70             output=None,
71             exit_code=1,
72         )
73 
74     source_files = await Get(
75         StrippedSourceFiles,
76         SourceFilesRequest([tgt.get(SourcesField) for tgt in request.component.members]),
77     )
78 
79     output_filename = f"{request.component.representative.address.path_safe_spec}.resources.jar"
80     output_files = [output_filename]
81 
82     # #16231: Valid JAR files need the directories of each resource file as well as the files
83     # themselves.
84 
85     paths = {Path(filename) for filename in source_files.snapshot.files}
86     directories = {parent for path in paths for parent in path.parents}
87     input_files = {str(path) for path in chain(paths, directories)}
88 
89     resources_jar_input_digest = source_files.snapshot.digest
90 
91     input_filenames = " ".join(shlex.quote(file) for file in sorted(input_files))
92 
93     resources_jar_result = await Get(
94         ProcessResult,
95         Process(
96             argv=[
97                 bash.path,
98                 "-c",
99                 " ".join(
100                     [
101                         touch.path,
102                         "-d 1980-01-01T00:00:00Z",
103                         input_filenames,
104                         "&&",
105                         "TZ=UTC",
106                         zip.path,
107                         "-oX",
108                         output_filename,
109                         input_filenames,
110                     ]
111                 ),
112             ],
113             description=f"Build resources JAR for {request.component}",
114             input_digest=resources_jar_input_digest,
115             output_files=output_files,
116             level=LogLevel.DEBUG,
117         ),
118     )
119 
120     output_digest = resources_jar_result.output_digest
121     cpe = ClasspathEntry(output_digest, output_files, [])
122 
123     merged_cpe_digest = await Get(
124         Digest,
125         MergeDigests(chain((cpe.digest,), (i.digest for i in direct_dependency_classpath_entries))),
126     )
127 
128     merged_cpe = ClasspathEntry.merge(
129         digest=merged_cpe_digest, entries=[cpe, *direct_dependency_classpath_entries]
130     )
131 
132     return FallibleClasspathEntry(output_filename, CompileResult.SUCCEEDED, merged_cpe, 0)
133 
134 
135 def rules():
136     return [
137         *collect_rules(),
138         *compile.rules(),
139         *stripped_source_files.rules(),
140         UnionRule(ClasspathEntryRequest, JvmResourcesRequest),
141     ]
142
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/python/pants/jvm/resources.py b/src/python/pants/jvm/resources.py
--- a/src/python/pants/jvm/resources.py
+++ b/src/python/pants/jvm/resources.py
@@ -98,8 +98,9 @@
                 "-c",
                 " ".join(
                     [
+                        "TZ=UTC",
                         touch.path,
-                        "-d 1980-01-01T00:00:00Z",
+                        "-t 198001010000.00",
                         input_filenames,
                         "&&",
                         "TZ=UTC",

{"golden_diff": "diff --git a/src/python/pants/jvm/resources.py b/src/python/pants/jvm/resources.py\n--- a/src/python/pants/jvm/resources.py\n+++ b/src/python/pants/jvm/resources.py\n@@ -98,8 +98,9 @@\n                 \"-c\",\n                 \" \".join(\n                     [\n+                        \"TZ=UTC\",\n                         touch.path,\n-                        \"-d 1980-01-01T00:00:00Z\",\n+                        \"-t 198001010000.00\",\n                         input_filenames,\n                         \"&&\",\n                         \"TZ=UTC\",\n", "issue": "JVM resource jar creation is broken on Mac by variation in `touch` command.\nBSD touch uses `-t` to set the timestamp whereas GNU touch uses `-d`. We use / assume the GNU binary as noted here: https://github.com/pantsbuild/pants/pull/16950#discussion_r1157196330\n\nAs discovered here: https://pantsbuild.slack.com/archives/C046T6T9U/p1680604327733559?thread_ts=1680604327.733559&cid=C046T6T9U\n\nWhere the error looks like:\n```\n 12:24:56.74 [ERROR] 1 Exception encountered:\n \n Engine traceback:\n   in select\n   in pants.core.goals.check.check\n   in pants.backend.scala.goals.check.scalac_check (scalac)\n   in pants.backend.scala.compile.scalac.compile_scala_source\n   in pants.jvm.compile.compile_classpath_entries\n   in pants.jvm.resources.assemble_resources_jar\n   in pants.engine.process.fallible_to_exec_result_or_raise\n Traceback (most recent call last):\n   File \"/Users/jbenito/.cache/pants/setup/bootstrap-Darwin-x86_64/pants.1Nnv7r/install/lib/python3.9/site-packages/pants/engine/process.py\", line 275, in fallible_to_exec_result_or_raise\n     raise ProcessExecutionFailure(\n pants.engine.process.ProcessExecutionFailure: Process 'Build resources JAR for sdk/transport-security-web-lib/src/test/resources:resources' failed with exit code 1.\n stdout:\n \n stderr:\n /usr/bin/touch: illegal option -- d\n usage:\n touch [-A [-][[hh]mm]SS] [-acfhm] [-r file] [-t [[CC]YY]MMDDhhmm[.SS]] file ...\n```\n\nIt appears #16950 was cherry picked back to 2.13.1 and 2.14.0; so Pants has been broken for JVM resource jars since 2.13.1.\n\n\n", "before_files": [{"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\n\nimport itertools\nimport logging\nimport shlex\nfrom itertools import chain\nfrom pathlib import Path\n\nfrom pants.core.target_types import ResourcesFieldSet, ResourcesGeneratorFieldSet\nfrom pants.core.util_rules import stripped_source_files\nfrom pants.core.util_rules.source_files import SourceFilesRequest\nfrom pants.core.util_rules.stripped_source_files import StrippedSourceFiles\nfrom pants.core.util_rules.system_binaries import BashBinary, TouchBinary, ZipBinary\nfrom pants.engine.fs import Digest, MergeDigests\nfrom pants.engine.internals.selectors import MultiGet\nfrom pants.engine.process import Process, ProcessResult\nfrom pants.engine.rules import Get, collect_rules, rule\nfrom pants.engine.target import SourcesField\nfrom pants.engine.unions import UnionRule\nfrom pants.jvm import compile\nfrom pants.jvm.compile import (\n    ClasspathDependenciesRequest,\n    ClasspathEntry,\n    ClasspathEntryRequest,\n    ClasspathEntryRequests,\n    CompileResult,\n    FallibleClasspathEntries,\n    FallibleClasspathEntry,\n)\nfrom pants.jvm.subsystems import JvmSubsystem\nfrom pants.util.logging import LogLevel\n\nlogger = logging.getLogger(__name__)\n\n\nclass JvmResourcesRequest(ClasspathEntryRequest):\n    field_sets = (\n        ResourcesFieldSet,\n        ResourcesGeneratorFieldSet,\n    )\n\n\n@rule(desc=\"Assemble resources\")\nasync def assemble_resources_jar(\n    zip: ZipBinary,\n    bash: BashBinary,\n    touch: TouchBinary,\n    jvm: JvmSubsystem,\n    request: JvmResourcesRequest,\n) -> FallibleClasspathEntry:\n    # Request the component's direct dependency classpath, and additionally any prerequisite.\n    # Filter out any dependencies that are generated by our current target so that each resource\n    # only appears in a single input JAR.\n    # NOTE: Generated dependencies will have the same dependencies as the current target, so we\n    # don't need to inspect those dependencies.\n    optional_prereq_request = [*((request.prerequisite,) if request.prerequisite else ())]\n    fallibles = await MultiGet(\n        Get(FallibleClasspathEntries, ClasspathEntryRequests(optional_prereq_request)),\n        Get(FallibleClasspathEntries, ClasspathDependenciesRequest(request, ignore_generated=True)),\n    )\n    direct_dependency_classpath_entries = FallibleClasspathEntries(\n        itertools.chain(*fallibles)\n    ).if_all_succeeded()\n\n    if direct_dependency_classpath_entries is None:\n        return FallibleClasspathEntry(\n            description=str(request.component),\n            result=CompileResult.DEPENDENCY_FAILED,\n            output=None,\n            exit_code=1,\n        )\n\n    source_files = await Get(\n        StrippedSourceFiles,\n        SourceFilesRequest([tgt.get(SourcesField) for tgt in request.component.members]),\n    )\n\n    output_filename = f\"{request.component.representative.address.path_safe_spec}.resources.jar\"\n    output_files = [output_filename]\n\n    # #16231: Valid JAR files need the directories of each resource file as well as the files\n    # themselves.\n\n    paths = {Path(filename) for filename in source_files.snapshot.files}\n    directories = {parent for path in paths for parent in path.parents}\n    input_files = {str(path) for path in chain(paths, directories)}\n\n    resources_jar_input_digest = source_files.snapshot.digest\n\n    input_filenames = \" \".join(shlex.quote(file) for file in sorted(input_files))\n\n    resources_jar_result = await Get(\n        ProcessResult,\n        Process(\n            argv=[\n                bash.path,\n                \"-c\",\n                \" \".join(\n                    [\n                        touch.path,\n                        \"-d 1980-01-01T00:00:00Z\",\n                        input_filenames,\n                        \"&&\",\n                        \"TZ=UTC\",\n                        zip.path,\n                        \"-oX\",\n                        output_filename,\n                        input_filenames,\n                    ]\n                ),\n            ],\n            description=f\"Build resources JAR for {request.component}\",\n            input_digest=resources_jar_input_digest,\n            output_files=output_files,\n            level=LogLevel.DEBUG,\n        ),\n    )\n\n    output_digest = resources_jar_result.output_digest\n    cpe = ClasspathEntry(output_digest, output_files, [])\n\n    merged_cpe_digest = await Get(\n        Digest,\n        MergeDigests(chain((cpe.digest,), (i.digest for i in direct_dependency_classpath_entries))),\n    )\n\n    merged_cpe = ClasspathEntry.merge(\n        digest=merged_cpe_digest, entries=[cpe, *direct_dependency_classpath_entries]\n    )\n\n    return FallibleClasspathEntry(output_filename, CompileResult.SUCCEEDED, merged_cpe, 0)\n\n\ndef rules():\n    return [\n        *collect_rules(),\n        *compile.rules(),\n        *stripped_source_files.rules(),\n        UnionRule(ClasspathEntryRequest, JvmResourcesRequest),\n    ]\n", "path": "src/python/pants/jvm/resources.py"}], "after_files": [{"content": "# Copyright 2021 Pants project contributors (see CONTRIBUTORS.md).\n# Licensed under the Apache License, Version 2.0 (see LICENSE).\n\nimport itertools\nimport logging\nimport shlex\nfrom itertools import chain\nfrom pathlib import Path\n\nfrom pants.core.target_types import ResourcesFieldSet, ResourcesGeneratorFieldSet\nfrom pants.core.util_rules import stripped_source_files\nfrom pants.core.util_rules.source_files import SourceFilesRequest\nfrom pants.core.util_rules.stripped_source_files import StrippedSourceFiles\nfrom pants.core.util_rules.system_binaries import BashBinary, TouchBinary, ZipBinary\nfrom pants.engine.fs import Digest, MergeDigests\nfrom pants.engine.internals.selectors import MultiGet\nfrom pants.engine.process import Process, ProcessResult\nfrom pants.engine.rules import Get, collect_rules, rule\nfrom pants.engine.target import SourcesField\nfrom pants.engine.unions import UnionRule\nfrom pants.jvm import compile\nfrom pants.jvm.compile import (\n    ClasspathDependenciesRequest,\n    ClasspathEntry,\n    ClasspathEntryRequest,\n    ClasspathEntryRequests,\n    CompileResult,\n    FallibleClasspathEntries,\n    FallibleClasspathEntry,\n)\nfrom pants.jvm.subsystems import JvmSubsystem\nfrom pants.util.logging import LogLevel\n\nlogger = logging.getLogger(__name__)\n\n\nclass JvmResourcesRequest(ClasspathEntryRequest):\n    field_sets = (\n        ResourcesFieldSet,\n        ResourcesGeneratorFieldSet,\n    )\n\n\n@rule(desc=\"Assemble resources\")\nasync def assemble_resources_jar(\n    zip: ZipBinary,\n    bash: BashBinary,\n    touch: TouchBinary,\n    jvm: JvmSubsystem,\n    request: JvmResourcesRequest,\n) -> FallibleClasspathEntry:\n    # Request the component's direct dependency classpath, and additionally any prerequisite.\n    # Filter out any dependencies that are generated by our current target so that each resource\n    # only appears in a single input JAR.\n    # NOTE: Generated dependencies will have the same dependencies as the current target, so we\n    # don't need to inspect those dependencies.\n    optional_prereq_request = [*((request.prerequisite,) if request.prerequisite else ())]\n    fallibles = await MultiGet(\n        Get(FallibleClasspathEntries, ClasspathEntryRequests(optional_prereq_request)),\n        Get(FallibleClasspathEntries, ClasspathDependenciesRequest(request, ignore_generated=True)),\n    )\n    direct_dependency_classpath_entries = FallibleClasspathEntries(\n        itertools.chain(*fallibles)\n    ).if_all_succeeded()\n\n    if direct_dependency_classpath_entries is None:\n        return FallibleClasspathEntry(\n            description=str(request.component),\n            result=CompileResult.DEPENDENCY_FAILED,\n            output=None,\n            exit_code=1,\n        )\n\n    source_files = await Get(\n        StrippedSourceFiles,\n        SourceFilesRequest([tgt.get(SourcesField) for tgt in request.component.members]),\n    )\n\n    output_filename = f\"{request.component.representative.address.path_safe_spec}.resources.jar\"\n    output_files = [output_filename]\n\n    # #16231: Valid JAR files need the directories of each resource file as well as the files\n    # themselves.\n\n    paths = {Path(filename) for filename in source_files.snapshot.files}\n    directories = {parent for path in paths for parent in path.parents}\n    input_files = {str(path) for path in chain(paths, directories)}\n\n    resources_jar_input_digest = source_files.snapshot.digest\n\n    input_filenames = \" \".join(shlex.quote(file) for file in sorted(input_files))\n\n    resources_jar_result = await Get(\n        ProcessResult,\n        Process(\n            argv=[\n                bash.path,\n                \"-c\",\n                \" \".join(\n                    [\n                        \"TZ=UTC\",\n                        touch.path,\n                        \"-t 198001010000.00\",\n                        input_filenames,\n                        \"&&\",\n                        \"TZ=UTC\",\n                        zip.path,\n                        \"-oX\",\n                        output_filename,\n                        input_filenames,\n                    ]\n                ),\n            ],\n            description=f\"Build resources JAR for {request.component}\",\n            input_digest=resources_jar_input_digest,\n            output_files=output_files,\n            level=LogLevel.DEBUG,\n        ),\n    )\n\n    output_digest = resources_jar_result.output_digest\n    cpe = ClasspathEntry(output_digest, output_files, [])\n\n    merged_cpe_digest = await Get(\n        Digest,\n        MergeDigests(chain((cpe.digest,), (i.digest for i in direct_dependency_classpath_entries))),\n    )\n\n    merged_cpe = ClasspathEntry.merge(\n        digest=merged_cpe_digest, entries=[cpe, *direct_dependency_classpath_entries]\n    )\n\n    return FallibleClasspathEntry(output_filename, CompileResult.SUCCEEDED, merged_cpe, 0)\n\n\ndef rules():\n    return [\n        *collect_rules(),\n        *compile.rules(),\n        *stripped_source_files.rules(),\n        UnionRule(ClasspathEntryRequest, JvmResourcesRequest),\n    ]\n", "path": "src/python/pants/jvm/resources.py"}]}