Set PRODUCT_NAME to bundle_name value

Tulsi assumed that the Product Name of a target will equal its label
name. With the addition of bundle_name, that is no longer true.

With this change, Product Name will be correctly set to bundle_name
when present.

--
PiperOrigin-RevId: 165262424
MOS_MIGRATED_REVID=165262424
diff --git a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
index 27e6eb8..39041f2 100644
--- a/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
+++ b/src/TulsiGenerator/Bazel/tulsi/tulsi_aspects.bzl
@@ -501,6 +501,7 @@
   rule = ctx.rule
   target_kind = rule.kind
   rule_attr = _get_opt_attr(rule, 'attr')
+  bundle_name = _get_opt_attr(target, 'apple_bundle.bundle_name')
 
   tulsi_info_files = depset()
   transitive_attributes = dict()
@@ -631,6 +632,7 @@
       attr=_struct_omitting_none(**all_attributes),
       build_file=ctx.build_file_path,
       bundle_id=bundle_id,
+      bundle_name=bundle_name,
       defines=target_defines,
       deps=compile_deps,
       extensions=extensions,
@@ -687,12 +689,10 @@
       if hasattr(dep, 'tulsi_generated_files'):
         tulsi_generated_files += dep.tulsi_generated_files
 
-  bundle_name = None
+  bundle_name = _get_opt_attr(target, 'apple_bundle.bundle_name')
   # TODO(b/37912213): Migrate to the new-style providers.
   if hasattr(target, 'apple_bundle'):
     artifacts = [target.apple_bundle.archive.path]
-    if hasattr(target.apple_bundle, 'bundle_name'):
-      bundle_name = target.apple_bundle.bundle_name
   else:  # TODO(b/33050780): Remove this branch when native rules are deleted.
     ipa_output_name = None
     if target_kind in _IPA_GENERATING_RULES:
diff --git a/src/TulsiGenerator/BazelAspectInfoExtractor.swift b/src/TulsiGenerator/BazelAspectInfoExtractor.swift
index 8179003..ed8430e 100644
--- a/src/TulsiGenerator/BazelAspectInfoExtractor.swift
+++ b/src/TulsiGenerator/BazelAspectInfoExtractor.swift
@@ -301,6 +301,7 @@
         extensions = nil
       }
       let bundleID = dict["bundle_id"] as? String
+      let bundleName = dict["bundle_name"] as? String
       let platformType = dict["platform_type"] as? String
 
       var extensionType: String?
@@ -333,6 +334,7 @@
                                 secondaryArtifacts: secondaryArtifacts,
                                 extensions: extensions,
                                 bundleID: bundleID,
+                                bundleName: bundleName,
                                 platformType: platformType,
                                 osDeploymentTarget: osDeploymentTarget,
                                 buildFilePath: buildFilePath,
diff --git a/src/TulsiGenerator/PBXTargetGenerator.swift b/src/TulsiGenerator/PBXTargetGenerator.swift
index 8fa49ed..c671c47 100644
--- a/src/TulsiGenerator/PBXTargetGenerator.swift
+++ b/src/TulsiGenerator/PBXTargetGenerator.swift
@@ -1342,7 +1342,8 @@
     var buildSettings = options.buildSettingsForTarget(name)
     buildSettings["TULSI_BUILD_PATH"] = entry.label.packageName!
 
-    buildSettings["PRODUCT_NAME"] = name
+
+    buildSettings["PRODUCT_NAME"] = entry.bundleName ?? name
     if let bundleID = entry.bundleID {
       buildSettings["PRODUCT_BUNDLE_IDENTIFIER"] = bundleID
     }
diff --git a/src/TulsiGenerator/RuleEntry.swift b/src/TulsiGenerator/RuleEntry.swift
index 91f2248..d7bd834 100644
--- a/src/TulsiGenerator/RuleEntry.swift
+++ b/src/TulsiGenerator/RuleEntry.swift
@@ -290,6 +290,9 @@
   // The CFBundleIdentifier associated with the target for this rule, if any.
   public let bundleID: String?
 
+  /// The bundle name associated with the target for this rule, if any.
+  public let bundleName: String?
+
   /// The CFBundleIdentifier of the watchOS extension target associated with this rule, if any.
   public let extensionBundleID: String?
 
@@ -360,6 +363,7 @@
        weakDependencies: Set<BuildLabel>? = nil,
        extensions: Set<BuildLabel>? = nil,
        bundleID: String? = nil,
+       bundleName: String? = nil,
        extensionBundleID: String? = nil,
        platformType: String? = nil,
        osDeploymentTarget: String? = nil,
@@ -404,6 +408,7 @@
       self.extensions = Set()
     }
     self.bundleID = bundleID
+    self.bundleName = bundleName
     self.extensionBundleID = extensionBundleID
     var deploymentTarget: DeploymentTarget? = nil
     if let platform = parsedPlatformType, let osVersion = osDeploymentTarget {
@@ -441,6 +446,7 @@
                    weakDependencies: Set<BuildLabel>? = nil,
                    extensions: Set<BuildLabel>? = nil,
                    bundleID: String? = nil,
+                   bundleName: String? = nil,
                    extensionBundleID: String? = nil,
                    platformType: String? = nil,
                    osDeploymentTarget: String? = nil,
@@ -464,6 +470,7 @@
               weakDependencies: weakDependencies,
               extensions: extensions,
               bundleID: bundleID,
+              bundleName: bundleName,
               extensionBundleID: extensionBundleID,
               platformType: platformType,
               osDeploymentTarget: osDeploymentTarget,
diff --git a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SimpleSkylarkProject.xcodeproj/project.pbxproj b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SimpleSkylarkProject.xcodeproj/project.pbxproj
index 338511a..3bfe257 100644
--- a/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SimpleSkylarkProject.xcodeproj/project.pbxproj
+++ b/src/TulsiGeneratorIntegrationTests/Resources/GoldenProjects/SimpleSkylarkProject.xcodeproj/project.pbxproj
@@ -668,7 +668,7 @@
 				INFOPLIST_FILE = "${PROJECT_FILE_PATH}/.tulsi/Resources/StubInfoPlist.plist";
 				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.Tulsi.Application;
-				PRODUCT_NAME = SkylarkApplication;
+				PRODUCT_NAME = SkylarkApp;
 				SDKROOT = iphoneos;
 				TULSI_BUILD_PATH = tulsi_e2e_simple_skylark;
 				TULSI_USE_DSYM = NO;
@@ -859,7 +859,7 @@
 				INFOPLIST_FILE = "${PROJECT_FILE_PATH}/.tulsi/Resources/StubInfoPlist.plist";
 				IPHONEOS_DEPLOYMENT_TARGET = 7.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.Tulsi.Application;
-				PRODUCT_NAME = SkylarkApplication;
+				PRODUCT_NAME = SkylarkApp;
 				SDKROOT = iphoneos;
 				TULSI_BUILD_PATH = tulsi_e2e_simple_skylark;
 				TULSI_USE_DSYM = YES;
@@ -1065,7 +1065,7 @@
 				OTHER_LDFLAGS = "-help";
 				OTHER_SWIFT_FLAGS = "-help";
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.Tulsi.Application;
-				PRODUCT_NAME = SkylarkApplication;
+				PRODUCT_NAME = SkylarkApp;
 				SDKROOT = iphoneos;
 				SWIFT_INSTALL_OBJC_HEADER = NO;
 				SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(PRODUCT_NAME).h";
@@ -1244,7 +1244,7 @@
 				OTHER_LDFLAGS = "-help";
 				OTHER_SWIFT_FLAGS = "-help";
 				PRODUCT_BUNDLE_IDENTIFIER = com.google.Tulsi.Application;
-				PRODUCT_NAME = SkylarkApplication;
+				PRODUCT_NAME = SkylarkApp;
 				SDKROOT = iphoneos;
 				SWIFT_INSTALL_OBJC_HEADER = NO;
 				SWIFT_OBJC_INTERFACE_HEADER_NAME = "$(PRODUCT_NAME).h";
diff --git a/src/TulsiGeneratorIntegrationTests/Resources/PlatformDependent.BUILD b/src/TulsiGeneratorIntegrationTests/Resources/PlatformDependent.BUILD
index afb39db..b037663 100644
--- a/src/TulsiGeneratorIntegrationTests/Resources/PlatformDependent.BUILD
+++ b/src/TulsiGeneratorIntegrationTests/Resources/PlatformDependent.BUILD
@@ -108,6 +108,7 @@
 skylark_ios_application(
     name = "SkylarkApplication",
     bundle_id = "com.google.Tulsi.Application",
+    bundle_name = "SkylarkApp",
     extensions = [":StickerExtension"],
     families = ["iphone"],
     infoplists = ["Application/Info.plist"],
diff --git a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
index 6df6c4b..1ed539a 100644
--- a/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
+++ b/src/TulsiGeneratorTests/PBXTargetGeneratorTests.swift
@@ -1338,6 +1338,70 @@
     }
   }
 
+  func testGenerateTargetWithBundleName() {
+    let targetName = "targetName"
+    let buildPath = "test/test1"
+    let buildTarget = "\(buildPath):\(targetName)"
+    let bundleName = "bundleName"
+    let rules = Set([
+      makeTestRuleEntry(buildTarget,
+                        type: "ios_application",
+                        bundleName: bundleName),
+      ])
+
+    do {
+      try targetGenerator.generateBuildTargetsForRuleEntries(rules, ruleEntryMap: [:])
+    } catch let e as NSError {
+      XCTFail("Failed to generate build targets with error \(e.localizedDescription)")
+    }
+
+    let topLevelConfigs = project.buildConfigurationList.buildConfigurations
+    XCTAssertEqual(topLevelConfigs.count, 0)
+
+    let targets = project.targetByName
+    XCTAssertEqual(targets.count, 1)
+
+    do {
+      let expectedBuildSettings = [
+        "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME": "Stub Launch Image",
+        "BAZEL_TARGET": buildTarget,
+        "BAZEL_TARGET_TYPE": "ios_application",
+        "DEBUG_INFORMATION_FORMAT": "dwarf",
+        "INFOPLIST_FILE": stubPlistPaths.defaultStub,
+        "PRODUCT_NAME": bundleName,
+        "SDKROOT": "iphoneos",
+        "TULSI_BUILD_PATH": buildPath,
+        "TULSI_USE_DSYM": "NO",
+      ]
+      let expectedTarget = TargetDefinition(
+        name: targetName,
+        buildConfigurations: [
+          BuildConfigurationDefinition(
+            name: "Debug",
+            expectedBuildSettings: debugBuildSettingsFromSettings(expectedBuildSettings)
+          ),
+          BuildConfigurationDefinition(
+            name: "Release",
+            expectedBuildSettings: releaseBuildSettingsFromSettings(expectedBuildSettings)
+          ),
+          BuildConfigurationDefinition(
+            name: "__TulsiTestRunner_Debug",
+            expectedBuildSettings: debugTestRunnerBuildSettingsFromSettings(expectedBuildSettings)
+          ),
+          BuildConfigurationDefinition(
+            name: "__TulsiTestRunner_Release",
+            expectedBuildSettings: releaseTestRunnerBuildSettingsFromSettings(expectedBuildSettings)
+          ),
+          ],
+        expectedBuildPhases: [
+          BazelShellScriptBuildPhaseDefinition(bazelURL: bazelURL, buildTarget: buildTarget)
+        ]
+      )
+      assertTarget(expectedTarget, inTargets: targets)
+    }
+
+  }
+
   func testGenerateWatchOSTarget() {
     let appTargetName = "targetName"
     let appBuildPath = "test/app"
@@ -2240,6 +2304,7 @@
                                  dependencies: Set<String> = Set(),
                                  extensions: Set<BuildLabel>? = nil,
                                  bundleID: String? = nil,
+                                 bundleName: String? = nil,
                                  extensionBundleID: String? = nil,
                                  platformType: String? = nil,
                                  osDeploymentTarget: String? = nil,
@@ -2253,6 +2318,7 @@
                              dependencies: dependencies,
                              extensions: extensions,
                              bundleID: bundleID,
+                             bundleName: bundleName,
                              extensionBundleID: extensionBundleID,
                              platformType: platformType,
                              osDeploymentTarget: osDeploymentTarget,
@@ -2274,6 +2340,7 @@
                                  dependencies: Set<String> = Set(),
                                  extensions: Set<BuildLabel>? = nil,
                                  bundleID: String? = nil,
+                                 bundleName: String? = nil,
                                  extensionBundleID: String? = nil,
                                  platformType: String? = nil,
                                  osDeploymentTarget: String? = nil,
@@ -2289,6 +2356,7 @@
                      dependencies: dependencies,
                      extensions: extensions,
                      bundleID: bundleID,
+                     bundleName: bundleName,
                      extensionBundleID: extensionBundleID,
                      platformType: platformType,
                      osDeploymentTarget: osDeploymentTarget,