mirror of https://github.com/pulumi/pulumi.git
87764984c8
11676: Pretty print PCL types in error messages r=iwahbe a=iwahbe This PR changes how type errors are printed, adding multi-line pretty printing to types. It is part of an effort to make PCL type error messages better (https://github.com/pulumi/pulumi/issues/11573). For comparison, here is the same error message with and without this PR: Before: ``` --- FAIL: TestGenerateExamples (0.00s) --- FAIL: TestGenerateExamples/aws-static-website (0.19s) example_transpile_test.go:124: Error Trace: /Users/ianwahbe/go/src/github.com/pulumi/pulumi-yaml/pkg/tests/example_transpile_test.go:124 Error: Should be false Test: TestGenerateExamples/aws-static-website Messages: aws-static-website.pp:9,11-21: cannot assign expression of type object({accelerateConfiguration = output(union(none, object({accelerationStatus = enum(aws-native:s3:BucketAccelerateConfigurationAccelerationStatus(string): cty.StringVal("Enabled"),cty.StringVal("Suspended"))}, annotated(0xc000ad06c0)))), accessControl = output(union(enum(aws-native:s3:BucketAccessControl(string): cty.StringVal("AuthenticatedRead"),cty.StringVal("AwsExecRead"),cty.StringVal("BucketOwnerFullControl"),cty.StringVal("BucketOwnerRead"),cty.StringVal("LogDeliveryWrite"),cty.StringVal("Private"),cty.StringVal("PublicRead"),cty.StringVal("PublicReadWrite")), none)), analyticsConfigurations = output(union(list(object({id = string, prefix = union(none, string), storageClassAnalysis = object({dataExport = union(none, object({destination = object({bucketAccountId = union(none, string), bucketArn = string, format = enum(aws-native:s3:BucketDestinationFormat(string): cty.StringVal("CSV"),cty.StringVal("ORC"),cty.StringVal("Parquet")), prefix = union(none, string)}, annotated(0xc000ad0e40)), outputSchemaVersion = string}, annotated(0xc000ad1140)))}, annotated(0xc000ad1240)), tagFilters = union(list(object({key = string, value = string}, annotated(0xc000ad1400))), none)}, annotated(0xc000ad1540))), none)), arn = output(string), bucketEncryption = output(union(none, object({serverSideEncryptionConfiguration = list(object({bucketKeyEnabled = union(bool, none), serverSideEncryptionByDefault = union(none, object({kMSMasterKeyID = union(none, string), sSEAlgorithm = enum(aws-native:s3:BucketServerSideEncryptionByDefaultSSEAlgorithm(string): cty.StringVal("aws:kms"),cty.StringVal("AES256"))}, annotated(0xc000ad1a80)))}, annotated(0xc000ad1c00)))}, annotated(0xc000ad1d40)))), bucketName = output(union(none, string)), corsConfiguration = output(union(none, object({corsRules = list(object({allowedHeaders = union(list(string), none), allowedMethods = list(enum(aws-native:s3:BucketCorsRuleAllowedMethodsItem(string): cty.StringVal("GET"),cty.StringVal("PUT"),cty.StringVal("HEAD"),cty.StringVal("POST"),cty.StringVal("DELETE"))), allowedOrigins = list(string), exposedHeaders = union(list(string), none), id = union(none, string), maxAge = union(int, none)}, annotated(0xc000b3e4c0)))}, annotated(0xc000b3f180)))), domainName = output(string), dualStackDomainName = output(string), id = output(string), intelligentTieringConfigurations = output(union(list(object({id = string, prefix = union(none, string), status = enum(aws-native:s3:BucketIntelligentTieringConfigurationStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled")), tagFilters = union(list(object({key = string, value = string}, annotated(0xc000ad1400))), none), tierings = list(object({accessTier = enum(aws-native:s3:BucketTieringAccessTier(string): cty.StringVal("ARCHIVE_ACCESS"),cty.StringVal("DEEP_ARCHIVE_ACCESS")), days = int}, annotated(0xc000b3f6c0)))}, annotated(0xc000b3f7c0))), none)), inventoryConfigurations = output(union(list(object({destination = object({bucketAccountId = union(none, string), bucketArn = string, format = enum(aws-native:s3:BucketDestinationFormat(string): cty.StringVal("CSV"),cty.StringVal("ORC"),cty.StringVal("Parquet")), prefix = union(none, string)}, annotated(0xc000ad0e40)), enabled = bool, id = string, includedObjectVersions = enum(aws-native:s3:BucketInventoryConfigurationIncludedObjectVersions(string): cty.StringVal("All"),cty.StringVal("Current")), optionalFields = union(list(enum(aws-native:s3:BucketInventoryConfigurationOptionalFieldsItem(string): cty.StringVal("Size"),cty.StringVal("LastModifiedDate"),cty.StringVal("StorageClass"),cty.StringVal("ETag"),cty.StringVal("IsMultipartUploaded"),cty.StringVal("ReplicationStatus"),cty.StringVal("EncryptionStatus"),cty.StringVal("ObjectLockRetainUntilDate"),cty.StringVal("ObjectLockMode"),cty.StringVal("ObjectLockLegalHoldStatus"),cty.StringVal("IntelligentTieringAccessTier"),cty.StringVal("BucketKeyStatus"))), none), prefix = union(none, string), scheduleFrequency = enum(aws-native:s3:BucketInventoryConfigurationScheduleFrequency(string): cty.StringVal("Daily"),cty.StringVal("Weekly"))}, annotated(0xc000b3ff40))), none)), lifecycleConfiguration = output(union(none, object({rules = list(object({abortIncompleteMultipartUpload = union(none, object({daysAfterInitiation = int}, annotated(0xc000002740))), expirationDate = union(none, string), expirationInDays = union(int, none), expiredObjectDeleteMarker = union(bool, none), id = union(none, string), noncurrentVersionExpiration = union(none, object({newerNoncurrentVersions = union(int, none), noncurrentDays = int}, annotated(0xc000002dc0))), noncurrentVersionExpirationInDays = union(int, none), noncurrentVersionTransition = union(none, object({newerNoncurrentVersions = union(int, none), storageClass = enum(aws-native:s3:BucketNoncurrentVersionTransitionStorageClass(string): cty.StringVal("DEEP_ARCHIVE"),cty.StringVal("GLACIER"),cty.StringVal("GLACIER_IR"),cty.StringVal("INTELLIGENT_TIERING"),cty.StringVal("ONEZONE_IA"),cty.StringVal("STANDARD_IA")), transitionInDays = int}, annotated(0xc000a70600))), noncurrentVersionTransitions = union(list(object({newerNoncurrentVersions = union(int, none), storageClass = enum(aws-native:s3:BucketNoncurrentVersionTransitionStorageClass(string): cty.StringVal("DEEP_ARCHIVE"),cty.StringVal("GLACIER"),cty.StringVal("GLACIER_IR"),cty.StringVal("INTELLIGENT_TIERING"),cty.StringVal("ONEZONE_IA"),cty.StringVal("STANDARD_IA")), transitionInDays = int}, annotated(0xc000a70600))), none), objectSizeGreaterThan = union(none, string), objectSizeLessThan = union(none, string), prefix = union(none, string), status = enum(aws-native:s3:BucketRuleStatus(string): cty.StringVal("Enabled"),cty.StringVal("Disabled")), tagFilters = union(list(object({key = string, value = string}, annotated(0xc000ad1400))), none), transition = union(none, object({storageClass = enum(aws-native:s3:BucketTransitionStorageClass(string): cty.StringVal("DEEP_ARCHIVE"),cty.StringVal("GLACIER"),cty.StringVal("GLACIER_IR"),cty.StringVal("INTELLIGENT_TIERING"),cty.StringVal("ONEZONE_IA"),cty.StringVal("STANDARD_IA")), transitionDate = union(none, string), transitionInDays = union(int, none)}, annotated(0xc000a71780))), transitions = union(list(object({storageClass = enum(aws-native:s3:BucketTransitionStorageClass(string): cty.StringVal("DEEP_ARCHIVE"),cty.StringVal("GLACIER"),cty.StringVal("GLACIER_IR"),cty.StringVal("INTELLIGENT_TIERING"),cty.StringVal("ONEZONE_IA"),cty.StringVal("STANDARD_IA")), transitionDate = union(none, string), transitionInDays = union(int, none)}, annotated(0xc000a71780))), none)}, annotated(0xc000a71bc0)))}, annotated(0xc000e74100)))), loggingConfiguration = output(union(none, object({destinationBucketName = union(none, string), logFilePrefix = union(none, string)}, annotated(0xc000e743c0)))), metricsConfigurations = output(union(list(object({accessPointArn = union(none, string), id = string, prefix = union(none, string), tagFilters = union(list(object({key = string, value = string}, annotated(0xc000ad1400))), none)}, annotated(0xc000e74840))), none)), notificationConfiguration = output(union(none, object({eventBridgeConfiguration = union(none, object({eventBridgeEnabled = bool}, annotated(0xc000e74b80))), lambdaConfigurations = union(list(object({event = string, filter = union(none, object({s3Key = object({rules = list(object({name = string, value = string}, annotated(0xc000e74e40)))}, annotated(0xc000e74f00))}, annotated(0xc000e74f80))), function = string}, annotated(0xc000e750c0))), none), queueConfigurations = union(list(object({event = string, filter = union(none, object({s3Key = object({rules = list(object({name = string, value = string}, annotated(0xc000e74e40)))}, annotated(0xc000e74f00))}, annotated(0xc000e74f80))), queue = string}, annotated(0xc000e75440))), none), topicConfigurations = union(list(object({event = string, filter = union(none, object({s3Key = object({rules = list(object({name = string, value = string}, annotated(0xc000e74e40)))}, annotated(0xc000e74f00))}, annotated(0xc000e74f80))), topic = string}, annotated(0xc000e757c0))), none)}, annotated(0xc000e759c0)))), objectLockConfiguration = output(union(none, object({objectLockEnabled = union(none, string), rule = union(none, object({defaultRetention = union(none, object({days = union(int, none), mode = union(enum(aws-native:s3:BucketDefaultRetentionMode(string): cty.StringVal("COMPLIANCE"),cty.StringVal("GOVERNANCE")), none), years = union(int, none)}, annotated(0xc000940080)))}, annotated(0xc000940300)))}, annotated(0xc000940440)))), objectLockEnabled = output(union(bool, none)), ownershipControls = output(union(none, object({rules = list(object({objectOwnership = union(enum(aws-native:s3:BucketOwnershipControlsRuleObjectOwnership(string): cty.StringVal("ObjectWriter"),cty.StringVal("BucketOwnerPreferred"),cty.StringVal("BucketOwnerEnforced")), none)}, annotated(0xc000940840)))}, annotated(0xc000940980)))), publicAccessBlockConfiguration = output(union(none, object({blockPublicAcls = union(bool, none), blockPublicPolicy = union(bool, none), ignorePublicAcls = union(bool, none), restrictPublicBuckets = union(bool, none)}, annotated(0xc000940dc0)))), regionalDomainName = output(string), replicationConfiguration = output(union(none, object({role = string, rules = list(object({deleteMarkerReplication = union(none, object({status = union(enum(aws-native:s3:BucketDeleteMarkerReplicationStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled")), none)}, annotated(0xc000941280))), destination = object({accessControlTranslation = union(none, object({owner = string}, annotated(0xc0009414c0))), account = union(none, string), bucket = string, encryptionConfiguration = union(none, object({replicaKmsKeyID = string}, annotated(0xc000941740))), metrics = union(none, object({eventThreshold = union(none, object({minutes = int}, annotated(0xc000941900))), status = enum(aws-native:s3:BucketMetricsStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled"))}, annotated(0xc000941ac0))), replicationTime = union(none, object({status = enum(aws-native:s3:BucketReplicationTimeStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled")), time = object({minutes = int}, annotated(0xc000941900))}, annotated(0xc000941d80))), storageClass = union(enum(aws-native:s3:BucketReplicationDestinationStorageClass(string): cty.StringVal("DEEP_ARCHIVE"),cty.StringVal("GLACIER"),cty.StringVal("GLACIER_IR"),cty.StringVal("INTELLIGENT_TIERING"),cty.StringVal("ONEZONE_IA"),cty.StringVal("REDUCED_REDUNDANCY"),cty.StringVal("STANDARD"),cty.StringVal("STANDARD_IA")), none)}, annotated(0xc0009a0000)), filter = union(none, object({and = union(none, object({prefix = union(none, string), tagFilters = union(list(object({key = string, value = string}, annotated(0xc000ad1400))), none)}, annotated(0xc0009a0500))), prefix = union(none, string), tagFilter = union(none, object({key = string, value = string}, annotated(0xc000ad1400)))}, annotated(0xc0009a0800))), id = union(none, string), prefix = union(none, string), priority = union(int, none), sourceSelectionCriteria = union(none, object({replicaModifications = union(none, object({status = enum(aws-native:s3:BucketReplicaModificationsStatus(string): cty.StringVal("Enabled"),cty.StringVal("Disabled"))}, annotated(0xc0009a0dc0))), sseKmsEncryptedObjects = union(none, object({status = enum(aws-native:s3:BucketSseKmsEncryptedObjectsStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled"))}, annotated(0xc0009a1000)))}, annotated(0xc0009a1140))), status = enum(aws-native:s3:BucketReplicationRuleStatus(string): cty.StringVal("Disabled"),cty.StringVal("Enabled"))}, annotated(0xc0009a1380)))}, annotated(0xc0009a1680)))), tags = output(union(list(object({key = string, value = string}, annotated(0xc0009a1840))), none)), urn = output(string), versioningConfiguration = output(union(none, object({status = enum(aws-native:s3:BucketVersioningConfigurationStatus(string): cty.StringVal("Enabled"),cty.StringVal("Suspended"))}, annotated(0xc0009a1a80)))), websiteConfiguration = output(union(none, object({errorDocument = union(none, string), indexDocument = union(none, string), redirectAllRequestsTo = union(none, object({hostName = string, protocol = union(enum(aws-native:s3:BucketRedirectAllRequestsToProtocol(string): cty.StringVal("http"),cty.StringVal("https")), none)}, annotated(0xc0009a1f40))), routingRules = union(list(object({redirectRule = object({hostName = union(none, string), httpRedirectCode = union(none, string), protocol = union(enum(aws-native:s3:BucketRedirectRuleProtocol(string): cty.StringVal("http"),cty.StringVal("https")), none), replaceKeyPrefixWith = union(none, string), replaceKeyWith = union(none, string)}, annotated(0xc000a24580)), routingRuleCondition = union(none, object({httpErrorCodeReturnedEquals = union(none, string), keyPrefixEquals = union(none, string)}, annotated(0xc000a249c0)))}, annotated(0xc000a24b40))), none)}, annotated(0xc000a24cc0)))), websiteURL = output(string)}, annotated(0xc000a25480)) to location of type union(output(string), output(union(string, type(aws:s3/bucket:Bucket))), string, type(aws:s3/bucket:Bucket), annotated(0xc000a25a80)): ; , and 1 other diagnostic(s) FAIL FAIL github.com/pulumi/pulumi-yaml/pkg/tests 1.511s ? github.com/pulumi/pulumi-yaml/pkg/version [no test files] FAIL ``` After: ``` --- FAIL: TestGenerateExamples (0.00s) --- FAIL: TestGenerateExamples/aws-static-website (1.88s) example_transpile_test.go:124: Error Trace: /Users/ianwahbe/go/src/github.com/pulumi/pulumi-yaml/pkg/tests/example_transpile_test.go:124 Error: Should be false Test: TestGenerateExamples/aws-static-website Messages: aws-static-website.pp:9,11-21: cannot assign expression of type { accelerateConfiguration: output({ accelerationStatus: enum("Enabled" | "Suspended") }?), accessControl: output(enum("AuthenticatedRead" | "AwsExecRead" | "BucketOwnerFullControl" | "BucketOwnerRead" | "LogDeliveryWrite" | "Private" | "PublicRead" | "PublicReadWrite")?), analyticsConfigurations: output(list({ id: string, prefix: string?, storageClassAnalysis: { dataExport: { destination: { bucketAccountId: string?, bucketArn: string, format: enum("CSV" | "ORC" | "Parquet"), prefix: string?, }, outputSchemaVersion: string, }?, }, tagFilters: list({ key: string, value: string })?, })?), arn: output(string), bucketEncryption: output({ serverSideEncryptionConfiguration: list({ bucketKeyEnabled: bool?, serverSideEncryptionByDefault: { kMSMasterKeyID: string?, sSEAlgorithm: enum("aws:kms" | "AES256") }?, }), }?), bucketName: output(string?), corsConfiguration: output({ corsRules: list({ allowedHeaders: list(string)?, allowedMethods: list(enum("GET" | "PUT" | "HEAD" | "POST" | "DELETE")), allowedOrigins: list(string), exposedHeaders: list(string)?, id: string?, maxAge: int?, }), }?), domainName: output(string), dualStackDomainName: output(string), id: output(string), intelligentTieringConfigurations: output(list({ id: string, prefix: string?, status: enum("Disabled" | "Enabled"), tagFilters: list({ key: string, value: string })?, tierings: list({ accessTier: enum("ARCHIVE_ACCESS" | "DEEP_ARCHIVE_ACCESS"), days: int }), })?), inventoryConfigurations: output(list({ destination: { bucketAccountId: string?, bucketArn: string, format: enum("CSV" | "ORC" | "Parquet"), prefix: string?, }, enabled: bool, id: string, includedObjectVersions: enum("All" | "Current"), optionalFields: list(enum("Size" | "LastModifiedDate" | "StorageClass" | "ETag" | "IsMultipartUploaded" | "ReplicationStatus" | "EncryptionStatus" | "ObjectLockRetainUntilDate" | "ObjectLockMode" | "ObjectLockLegalHoldStatus" | "IntelligentTieringAccessTier" | "BucketKeyStatus"))?, prefix: string?, scheduleFrequency: enum("Daily" | "Weekly"), })?), lifecycleConfiguration: output({ rules: list({ abortIncompleteMultipartUpload: { daysAfterInitiation: int }?, expirationDate: string?, expirationInDays: int?, expiredObjectDeleteMarker: bool?, id: string?, noncurrentVersionExpiration: { newerNoncurrentVersions: int?, noncurrentDays: int }?, noncurrentVersionExpirationInDays: int?, noncurrentVersionTransition: { newerNoncurrentVersions: int?, storageClass: enum("DEEP_ARCHIVE" | "GLACIER" | "GLACIER_IR" | "INTELLIGENT_TIERING" | "ONEZONE_IA" | "STANDARD_IA"), transitionInDays: int, }?, noncurrentVersionTransitions: list({ newerNoncurrentVersions: int?, storageClass: enum("DEEP_ARCHIVE" | "GLACIER" | "GLACIER_IR" | "INTELLIGENT_TIERING" | "ONEZONE_IA" | "STANDARD_IA"), transitionInDays: int, })?, objectSizeGreaterThan: string?, objectSizeLessThan: string?, prefix: string?, status: enum("Enabled" | "Disabled"), tagFilters: list({ key: string, value: string })?, transition: { storageClass: enum("DEEP_ARCHIVE" | "GLACIER" | "GLACIER_IR" | "INTELLIGENT_TIERING" | "ONEZONE_IA" | "STANDARD_IA"), transitionDate: string?, transitionInDays: int?, }?, transitions: list({ storageClass: enum("DEEP_ARCHIVE" | "GLACIER" | "GLACIER_IR" | "INTELLIGENT_TIERING" | "ONEZONE_IA" | "STANDARD_IA"), transitionDate: string?, transitionInDays: int?, })?, }), }?), loggingConfiguration: output({ destinationBucketName: string?, logFilePrefix: string? }?), metricsConfigurations: output(list({ accessPointArn: string?, id: string, prefix: string?, tagFilters: list({ key: string, value: string })?, })?), notificationConfiguration: output({ eventBridgeConfiguration: { eventBridgeEnabled: bool }?, lambdaConfigurations: list({ event: string, filter: { s3Key: { rules: list({ name: string, value: string }) } }?, function: string, })?, queueConfigurations: list({ event: string, filter: { s3Key: { rules: list({ name: string, value: string }) } }?, queue: string, })?, topicConfigurations: list({ event: string, filter: { s3Key: { rules: list({ name: string, value: string }) } }?, topic: string, })?, }?), objectLockConfiguration: output({ objectLockEnabled: string?, rule: { defaultRetention: { days: int?, mode: enum("COMPLIANCE" | "GOVERNANCE")?, years: int? }? }?, }?), objectLockEnabled: output(bool?), ownershipControls: output({ rules: list({ objectOwnership: enum("ObjectWriter" | "BucketOwnerPreferred" | "BucketOwnerEnforced")? }), }?), publicAccessBlockConfiguration: output({ blockPublicAcls: bool?, blockPublicPolicy: bool?, ignorePublicAcls: bool?, restrictPublicBuckets: bool?, }?), regionalDomainName: output(string), replicationConfiguration: output({ role: string, rules: list({ deleteMarkerReplication: { status: enum("Disabled" | "Enabled")? }?, destination: { accessControlTranslation: { owner: string }?, account: string?, bucket: string, encryptionConfiguration: { replicaKmsKeyID: string }?, metrics: { eventThreshold: { minutes: int }?, status: enum("Disabled" | "Enabled") }?, replicationTime: { status: enum("Disabled" | "Enabled"), time: { minutes: int } }?, storageClass: enum("DEEP_ARCHIVE" | "GLACIER" | "GLACIER_IR" | "INTELLIGENT_TIERING" | "ONEZONE_IA" | "REDUCED_REDUNDANCY" | "STANDARD" | "STANDARD_IA")?, }, filter: { and: { prefix: string?, tagFilters: list({ key: string, value: string })? }?, prefix: string?, tagFilter: { key: string, value: string }?, }?, id: string?, prefix: string?, priority: int?, sourceSelectionCriteria: { replicaModifications: { status: enum("Enabled" | "Disabled") }?, sseKmsEncryptedObjects: { status: enum("Disabled" | "Enabled") }?, }?, status: enum("Disabled" | "Enabled"), }), }?), tags: output(list({ key: string, value: string })?), urn: output(string), versioningConfiguration: output({ status: enum("Enabled" | "Suspended") }?), websiteConfiguration: output({ errorDocument: string?, indexDocument: string?, redirectAllRequestsTo: { hostName: string, protocol: enum("http" | "https")? }?, routingRules: list({ redirectRule: { hostName: string?, httpRedirectCode: string?, protocol: enum("http" | "https")?, replaceKeyPrefixWith: string?, replaceKeyWith: string?, }, routingRuleCondition: { httpErrorCodeReturnedEquals: string?, keyPrefixEquals: string? }?, })?, }?), websiteURL: output(string), } to location of type output(string) | output(string | type(aws:s3/bucket:Bucket)) | string | type(aws:s3/bucket:Bucket): ; , and 1 other diagnostic(s) FAIL FAIL github.com/pulumi/pulumi-yaml/pkg/tests 2.401s ? github.com/pulumi/pulumi-yaml/pkg/version [no test files] FAIL ``` Co-authored-by: Ian Wahbe <ian@wahbe.com> |
||
---|---|---|
.. | ||
authhelpers | ||
backend | ||
cmd/pulumi | ||
codegen | ||
engine | ||
graph | ||
operations | ||
resource | ||
secrets | ||
testing/integration | ||
util | ||
version | ||
README.md | ||
go.mod | ||
go.sum |
README.md
pulumi/pkg
While pulumi/sdk maintains strict backwards compatibility guarantees, code under pkg/ is handled more informally: while breaking changes are still discouraged they may happen when they make sense.