diff --git a/project/Dependencies.scala b/project/Dependencies.scala index b551497da..ac3055dff 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -20,7 +20,7 @@ object Dependencies { val protocolRaw = "com.raw-labs" %% "protocol-raw" % "0.50.0" - val protocolCompiler = "com.raw-labs" %% "protocol-compiler" % "0.51.0" + val protocolCompiler = "com.raw-labs" %% "protocol-compiler" % "0.52.0" val scalaLogging = "com.typesafe.scala-logging" %% "scala-logging" % "3.9.5" diff --git a/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/base/errors/Errors.scala b/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/base/errors/Errors.scala index d4d84770b..57e4a60c2 100644 --- a/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/base/errors/Errors.scala +++ b/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/base/errors/Errors.scala @@ -54,6 +54,17 @@ object MissingSecretWarning { val message: String = "secret is not defined" } +final case class S3BucketWarning( + node: BaseNode, + reason: String = S3BucketWarning.message +) extends WarningCompilerMessage { + val code: String = S3BucketWarning.code +} +object S3BucketWarning { + val code: String = "s3Bucket" + val message: String = "S3 bucket credentials are deprecated. Use AWS keys instead." +} + trait InfoCompilerMessage extends CompilerMessage trait HintCompilerMessage extends CompilerMessage trait ErrorCompilerMessage extends CompilerMessage diff --git a/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/snapi/SemanticAnalyzer.scala b/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/snapi/SemanticAnalyzer.scala index ff05d66e9..be4c24465 100644 --- a/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/snapi/SemanticAnalyzer.scala +++ b/snapi-frontend/src/main/scala/com/rawlabs/snapi/frontend/snapi/SemanticAnalyzer.scala @@ -536,8 +536,7 @@ class SemanticAnalyzer(val tree: SourceTree.SourceTree)(implicit programContext: // we check for errors in errorDef, if there are no errors, we are interested in nonErrors(hints, warnings, infos) override protected def nonErrorDef: SourceNode ==> Seq[CompilerMessage] = { val snapiNonErrors: PartialFunction[SourceNode, Seq[CompilerMessage]] = { - case e @ FunApp(Proj(exp, "Secret"), parameters) - if tipe(exp) == PackageType("Environment") && !isStagedCompiler => + case e @ FunApp(Proj(exp, "Secret"), _) if tipe(exp) == PackageType("Environment") && !isStagedCompiler => tipe(exp) match { case PackageType("Environment") => // Use getValue to confirm Environment.Secret succeeds. The getValue function also handles potentially unexpected nullables and tryables. @@ -554,6 +553,22 @@ class SemanticAnalyzer(val tree: SourceTree.SourceTree)(implicit programContext: } case _ => Seq.empty } + case e @ FunApp(Proj(exp, "Build"), _) if tipe(exp) == PackageType("Environment") && !isStagedCompiler => + tipe(exp) match { + case PackageType("S3") => + // Use getValue to confirm it succeeds. The getValue function also handles potentially unexpected nullables and tryables. + // We give it a dummy report which states the expected type is the actual type, so that is skips these checks + val report = CompatibilityReport(tipe(e), tipe(e)) + // Try execute "Environment.Secret()" + val v = getValue(report, e) + v match { + // If getValue returns an error which means the staged compiler failed to execute "Environment.Secret()" code + // We return a warning that the secret is missing. + case Right(SnapiTryValue(Left(error))) => Seq(S3BucketWarning(e)) + case _ => Seq.empty + } + case _ => Seq.empty + } } snapiNonErrors.orElse(super.nonErrorDef) } diff --git a/snapi-truffle/src/main/java/com/rawlabs/snapi/truffle/ast/expressions/builtin/location_package/LocationFromS3Node.java b/snapi-truffle/src/main/java/com/rawlabs/snapi/truffle/ast/expressions/builtin/location_package/LocationFromS3Node.java index 8f8135bb8..7131f80b9 100644 --- a/snapi-truffle/src/main/java/com/rawlabs/snapi/truffle/ast/expressions/builtin/location_package/LocationFromS3Node.java +++ b/snapi-truffle/src/main/java/com/rawlabs/snapi/truffle/ast/expressions/builtin/location_package/LocationFromS3Node.java @@ -14,7 +14,7 @@ import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; -import com.rawlabs.protocol.compiler.AwsConfig; +import com.rawlabs.protocol.compiler.AWSAccessKeysConfig; import com.rawlabs.protocol.compiler.LocationConfig; import com.rawlabs.snapi.truffle.SnapiContext; import com.rawlabs.snapi.truffle.ast.ExpressionNode; @@ -64,10 +64,14 @@ public Object executeGeneric(VirtualFrame frame) { String credName = (String) this.awsCredential.executeGeneric(frame); // getLocationConfig throws if the credential isn't found. LocationConfig locationConfig = context.getLocationConfig(credName); - if (!locationConfig.hasAws()) { + if (locationConfig.hasError()) { + String message = locationConfig.getError().getMessage(); + throw new TruffleRuntimeException(message); + } + if (!locationConfig.hasAwsAccessKeys()) { throw new TruffleRuntimeException("credential is not an AWS credential"); } - AwsConfig awsConfig = locationConfig.getAws(); + AWSAccessKeysConfig awsConfig = locationConfig.getAwsAccessKeys(); maybeAccessKey = new Some(awsConfig.getAccessKey()); maybeSecretKey = new Some(awsConfig.getSecretKey()); }