Enable tree artifact outputs by default.

- Support rsyncing tree artifacts.
- Verify that rsync is used to copy over files
instead of unzipping (test with Buttons project).

PiperOrigin-RevId: 243300901
diff --git a/src/TulsiEndToEndTests/TulsiEndToEndTest.swift b/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
index 1def283..6b129ce 100644
--- a/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
+++ b/src/TulsiEndToEndTests/TulsiEndToEndTest.swift
@@ -175,7 +175,8 @@
     return xcodeProjectURL
   }
 
-  // Runs Xcode tests on the given Xcode project and scheme.
+  // Runs Xcode tests on the given Xcode project and scheme. This verifies that
+  // the test passes and that rsync behavior is used to copy files.
   func testXcodeProject(_ xcodeProjectURL: URL, scheme: String) {
     let destination = "platform=iOS Simulator,name=\(TulsiEndToEndTest.simulatorName),OS=\(TulsiEndToEndTest.targetVersion)"
     let completionInfo = ProcessRunner.launchProcessSync("/usr/bin/xcodebuild",
@@ -189,6 +190,7 @@
 
     if let stdoutput = String(data: completionInfo.stdout, encoding: .utf8),
       let result = stdoutput.split(separator: "\n").last {
+      XCTAssert(stdoutput.contains("Rsyncing"), "Failed to find 'Rsyncing' in:\n\(stdoutput)")
       if (String(result) != "** TEST SUCCEEDED **") {
         print(stdoutput)
         XCTFail("\(completionInfo.commandlineString) did not return test success. Exit code: \(completionInfo.terminationStatus)")
diff --git a/src/TulsiGenerator/BazelSettingsProvider.swift b/src/TulsiGenerator/BazelSettingsProvider.swift
index cbe7c27..4997566 100644
--- a/src/TulsiGenerator/BazelSettingsProvider.swift
+++ b/src/TulsiGenerator/BazelSettingsProvider.swift
@@ -107,6 +107,7 @@
   static let tulsiCommonNonCacheableFlags = BazelFlags(build:  [
       "--define=apple.add_debugger_entitlement=1",
       "--define=apple.propagate_embedded_extra_outputs=1",
+      "--define=apple.experimental.tree_artifact_outputs=1",
   ])
 
   /// Cache-able flags added by Tulsi for builds.
diff --git a/src/TulsiGenerator/Scripts/bazel_build.py b/src/TulsiGenerator/Scripts/bazel_build.py
index 0fb4cc3..701cbde 100755
--- a/src/TulsiGenerator/Scripts/bazel_build.py
+++ b/src/TulsiGenerator/Scripts/bazel_build.py
@@ -881,8 +881,9 @@
       if exit_code:
         return exit_code
     else:
-      self._InstallBundle(primary_artifact,
-                          xcode_artifact_path)
+      self._RsyncBundle(os.path.basename(primary_artifact),
+                        primary_artifact,
+                        xcode_artifact_path)
 
       # When the rules output a tree artifact, Tulsi will copy the bundle as is
       # into the expected Xcode output location. But because they're copied as
@@ -1066,7 +1067,7 @@
 
   def _RsyncBundle(self, source_path, full_source_path, output_path):
     """Rsyncs the given bundle to the given expected output path."""
-    self._PrintVerbose('Copying %s to %s' % (source_path, output_path))
+    self._PrintVerbose('Rsyncing %s to %s' % (source_path, output_path))
 
     # rsync behavior changes based on presence of a trailing slash.
     if not full_source_path.endswith('/'):