public generateProjectFile()

in packages/jsii-pacmak/lib/targets/dotnet/filegenerator.ts [48:168]


  public generateProjectFile(
    dependencies: Map<string, DotNetDependency>,
    iconFile?: string,
  ) {
    const assembly = this.assm;
    const packageId: string = assembly.targets!.dotnet!.packageId;

    const projectFilePath: string = path.join(packageId, `${packageId}.csproj`);

    // Construct XML csproj content.
    // headless removes the <xml?> head node so that the first node is the <Project> node
    const rootNode = xmlbuilder.create('Project', {
      encoding: 'UTF-8',
      headless: true,
    });
    rootNode.att('Sdk', 'Microsoft.NET.Sdk');
    const propertyGroup = rootNode.ele('PropertyGroup');
    const dotnetInfo = assembly.targets!.dotnet;

    propertyGroup.comment('Package Identification');
    propertyGroup.ele('Description', this.getDescription());
    if (iconFile != null) {
      propertyGroup.ele('PackageIcon', iconFile.split(/[/\\]+/).join('\\'));
      // We also need to actually include the icon in the package
      const noneNode = rootNode.ele('ItemGroup').ele('None');
      noneNode.att('Include', iconFile.split(/[/\\]+/).join('\\'));
      noneNode.att('Pack', 'true');
      noneNode.att(
        'PackagePath',
        `\\${path
          .dirname(iconFile)
          .split(/[/\\]+/)
          .join('\\')}`,
      );
    }
    // We continue to include the PackageIconUrl even if we put PackageIcon for backwards compatibility, as suggested
    // by https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packageicon
    if (dotnetInfo!.iconUrl != null) {
      propertyGroup.ele('PackageIconUrl', dotnetInfo!.iconUrl);
    }
    propertyGroup.ele('PackageId', packageId);
    propertyGroup.ele('PackageLicenseExpression', assembly.license);
    propertyGroup.ele('PackageVersion', this.getDecoratedVersion(assembly));
    if (dotnetInfo!.title != null) {
      propertyGroup.ele('Title', dotnetInfo!.title);
    }

    propertyGroup.comment('Additional Metadata');
    propertyGroup.ele('Authors', assembly.author.name);
    if (assembly.author.organization) {
      propertyGroup.ele('Company', assembly.author.name);
    }
    if (assembly.keywords) {
      propertyGroup.ele('PackageTags', assembly.keywords.join(';'));
    }
    propertyGroup.ele('Language', 'en-US');
    propertyGroup.ele('ProjectUrl', assembly.homepage);
    propertyGroup.ele('RepositoryUrl', assembly.repository.url);
    propertyGroup.ele('RepositoryType', assembly.repository.type);

    propertyGroup.comment('Build Configuration');
    propertyGroup.ele('GenerateDocumentationFile', 'true');
    propertyGroup.ele('GeneratePackageOnBuild', 'true');
    propertyGroup.ele('IncludeSymbols', 'true');
    propertyGroup.ele('IncludeSource', 'true');
    propertyGroup.ele('Nullable', 'enable');
    propertyGroup.ele('SymbolPackageFormat', 'snupkg');
    propertyGroup.ele('TargetFramework', TARGET_FRAMEWORK);
    // Transparently rolll forward across major SDK releases if needed
    propertyGroup.ele('RollForward', 'Major');

    const itemGroup1 = rootNode.ele('ItemGroup');
    const embeddedResource = itemGroup1.ele('EmbeddedResource');
    embeddedResource.att('Include', this.tarballFileName);

    const itemGroup2 = rootNode.ele('ItemGroup');
    const packageReference = itemGroup2.ele('PackageReference');
    packageReference.att('Include', 'Amazon.JSII.Runtime');
    packageReference.att('Version', toNuGetVersionRange(`^${VERSION}`));

    dependencies.forEach((value: DotNetDependency) => {
      if (value.partOfCompilation) {
        const dependencyReference = itemGroup2.ele('ProjectReference');
        dependencyReference.att(
          'Include',
          `../${value.packageId}/${value.packageId}.csproj`,
        );
      } else {
        const dependencyReference = itemGroup2.ele('PackageReference');
        dependencyReference.att('Include', value.packageId);
        dependencyReference.att('Version', value.version);
      }
    });

    const warnings = rootNode.ele('PropertyGroup');
    // Suppress warnings about [Obsolete] members, this is the author's choice!
    warnings.comment('Silence [Obsolete] warnings');
    warnings.ele('NoWarn').text('0612,0618');
    // Treat select warnings as errors, as these are likely codegen bugs:
    warnings.comment(
      'Treat warnings symptomatic of code generation bugs as errors',
    );
    warnings.ele(
      'WarningsAsErrors',
      [
        '0108', // 'member1' hides inherited member 'member2'. Use the new keyword if hiding was intended.
        '0109', // The member 'member' does not hide an inherited member. The new keyword is not required.
      ].join(','),
    );
    const xml = rootNode.end({ pretty: true, spaceBeforeSlash: true });

    // Sending the xml content to the codemaker to ensure the file is written
    // and added to the file list for tracking
    this.code.openFile(projectFilePath);
    this.code.open(xml);
    // Unindent for the next file
    this.code.close();
    this.code.closeFile(projectFilePath);

    logging.debug(`Written to ${projectFilePath}`);
  }