Skip to content

Commit

Permalink
feat: Switch to download binary on startup (#12)
Browse files Browse the repository at this point in the history
- Update the plugin to download the binary as required on launch 
	- only happens on first download
- Add a button to Update infracost on the settings tab

<img width="983" alt="image"
src="https://github.com/infracost/jetbrains-infracost/assets/3049157/96554128-7f06-46ac-a2d4-f9eb35f8ece4">
  • Loading branch information
owenrumney authored Jul 10, 2024
1 parent 26ce56a commit 8712a3c
Show file tree
Hide file tree
Showing 18 changed files with 369 additions and 261 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ jobs:
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
build-scan-terms-of-use-agree: "yes"

- name: Download latest Infracost
run: ./scripts/download.sh

- name: Run build plugin
run: ./gradlew buildPlugin

Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,44 @@

## [Unreleased]

## [1.2.0] - 2024-07-09

### Changed

- Download the latest Infracost binary on plugin rather than bundling it

## [1.1.1] - 2024-07-04

### Fixed

- Limit subsequent runs to one queued run, this handles large scale saves and button mashing

### Changed

- Set the platform identifier to jetbrains

## [1.1.0] - 2024-07-02

### Added

- Support for config files
- Support for usage files

## [1.0.2] - 2024-07-01

### Fixed

- Update linux binaries path
- Make the "connect to Infracost" link more simple

## [1.0.1] - 2024-07-01

### Fixed

- Updates to readme

## [1.0.0] - 2024-06-29

### Added

- Initial release of the Infracost plugin for JetBrains IDEs.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
## Description

<!-- Plugin description -->
Infracost is a JetBrains IDE plugin that allows you to shift left on your Cloud costs by providing cost estimates for your Terraform code.
Infracost is a JetBrains IDE plugin that allows you to shift left on your Cloud costs by providing cost estimates for
your Terraform code.

Infracost is a companion to the [Infracost CLI](https://www.infracost.io/docs/integrations/ci-cd) and provides a way to view cost estimates directly in your IDE.
Infracost is a companion to the [Infracost CLI](https://www.infracost.io/docs/integrations/ci-cd) and provides a way to
view cost estimates directly in your IDE.
<!-- Plugin description end -->

## Features
Expand All @@ -30,4 +32,6 @@ You can install the plugin from the JetBrains Plugin Repository.
4. Restart the IDE
5. Open a Terraform file and click on the `Infracost` tab at the bottom of the IDE
6. Click on `Refresh` to get the cost estimate
7. Use our ![CI/CD integrations](https://www.infracost.io/docs/integrations/cicd/) to add cost estimates to pull requests. This provides your team with a safety net as people can understand cloud costs upfront, and discuss them as part of your workflow.
7. Use our ![CI/CD integrations](https://www.infracost.io/docs/integrations/cicd/) to add cost estimates to pull
requests. This provides your team with a safety net as people can understand cloud costs upfront, and discuss them as
part of your workflow.
14 changes: 9 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ repositories {
}

dependencies {
implementation("org.apache.commons:commons-compress:1.21")
}

kotlin {
Expand Down Expand Up @@ -82,10 +83,10 @@ tasks {
changeNotes = properties("pluginVersion").map { pluginVersion ->
with(changelog) {
renderItem(
(getOrNull(pluginVersion) ?: getUnreleased())
.withHeader(false)
.withEmptySections(false),
Changelog.OutputType.HTML,
(getOrNull(pluginVersion) ?: getUnreleased())
.withHeader(false)
.withEmptySections(false),
Changelog.OutputType.HTML,
)
}
}
Expand All @@ -109,6 +110,9 @@ tasks {
publishPlugin {
dependsOn("patchChangelog", "signPlugin")
token = environment("PUBLISH_TOKEN")
channels = properties("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) }
channels = properties("pluginVersion").map {
listOf(
it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" })
}
}
}
29 changes: 13 additions & 16 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html

pluginGroup = io.infracost.plugins
pluginName = Infracost
pluginRepositoryUrl = https://github.com/infracost/jetbrains-infracost
pluginVersion = 1.1.1

pluginSinceBuild = 232
pluginUntilBuild = 242.*

platformType = IC
platformVersion = 2023.2.7
platformPlugins =
gradleVersion = 8.8
kotlin.stdlib.default.dependency = false
org.gradle.configuration-cache = true
org.gradle.caching = true
pluginGroup=io.infracost.plugins
pluginName=Infracost
pluginRepositoryUrl=https://github.com/infracost/jetbrains-infracost
pluginVersion=1.2.0
pluginSinceBuild=232
pluginUntilBuild=242.*
platformType=IC
platformVersion=2023.2.7
platformPlugins=
gradleVersion=8.8
kotlin.stdlib.default.dependency=false
org.gradle.configuration-cache=true
org.gradle.caching=true
70 changes: 0 additions & 70 deletions scripts/download.sh

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.infracost.plugins.infracost.actions

import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProgressManager
import com.intellij.openapi.project.Project
import io.infracost.plugins.infracost.actions.tasks.InfracostDownloadBinaryTask
import javax.swing.SwingUtilities

class DownloadInfracostAction : AnAction() {

override fun actionPerformed(e: AnActionEvent) {
ProgressManager.getInstance().run(InfracostDownloadBinaryTask(e.project!!, false))
}

companion object {
fun runDownload(project: Project, initial: Boolean = false) {
val runner =
InfracostDownloadBinaryTask(project, initial)
if (SwingUtilities.isEventDispatchThread()) {
ProgressManager.getInstance().run(runner)
} else {
ApplicationManager.getApplication().invokeLater(runner)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ class RunInfracostAction : AnAction() {
}

if (running.get()) {
// If a run is already in progress, queue the next run
next.set(runner)
// If a run is already in progress, queue the next run if not already queued
next.compareAndSet(null, runner)
return
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package io.infracost.plugins.infracost.actions.tasks

import com.intellij.execution.ExecutionException
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task.Backgroundable
import com.intellij.openapi.project.Project
import io.infracost.plugins.infracost.actions.CheckAuthAction
import io.infracost.plugins.infracost.binary.InfracostBinary
import io.infracost.plugins.infracost.ui.notify.InfracostNotificationGroup
import java.io.BufferedReader
import java.io.InputStreamReader
Expand All @@ -15,36 +16,27 @@ import javax.swing.SwingUtilities
internal class InfracostAuthRunTask(
private val project: Project,
private val callback: Consumer<Boolean>
) : InfracostTask(project, "Authenticate Infracost", false), Runnable {
) : Backgroundable(project, "Authenticate Infracost", false), Runnable {
override fun run(indicator: ProgressIndicator) {
this.run()
}

override fun run() {
if (!ensureBinaryAvailable()) {
InfracostNotificationGroup.notifyError(project, "Infracost binary not found")
return
}
val commandParts: MutableList<String?> = ArrayList()
commandParts.add(InfracostBinary.binaryFile)
commandParts.add("auth")
commandParts.add("login")

val commandParams: MutableList<String?> = ArrayList()
commandParams.add(binaryFile)
commandParams.add("auth")
commandParams.add("login")
val command = ProcessBuilder(commandParts)
command.environment().set("INFRACOST_CLI_PLATFORM", "jetbrains")
command.environment().set("INFRACOST_SKIP_UPDATE_CHECK", "true")
command.environment().set("INFRACOST_GRAPH_EVALUATOR", "true")
command.environment().set("INFRACOST_NO_COLOR", "true")

val commandLine =
GeneralCommandLine(commandParams)
.withEnvironment(
mapOf(
"INFRACOST_SKIP_UPDATE_CHECK" to "true",
"INFRACOST_GRAPH_EVALUATOR" to "true",
"INFRACOST_NO_COLOR" to "true",
"INFRACOST_CLI_PLATFORM" to "jetbrains",
)
)
ApplicationManager.getApplication().executeOnPooledThread {
try {
try {
val process = Runtime.getRuntime().exec(commandLine.commandLineString)
val process = command.start()
val inputReader = BufferedReader(InputStreamReader(process.inputStream))
val inputThread = Thread {
try {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package io.infracost.plugins.infracost.actions.tasks

import com.intellij.execution.ExecutionException
import com.intellij.execution.configurations.GeneralCommandLine
import com.intellij.execution.process.OSProcessHandler
import com.intellij.execution.process.ScriptRunnerUtil
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.progress.Task.Backgroundable
import com.intellij.openapi.project.Project
import io.infracost.plugins.infracost.binary.InfracostBinary
import io.infracost.plugins.infracost.ui.notify.InfracostNotificationGroup
import java.io.File
import java.nio.file.Paths
Expand All @@ -16,25 +17,19 @@ internal class InfracostBackgroundRunTask(
private val project: Project,
private val resultFile: File,
private val callback: BiConsumer<Project, File>
) : InfracostTask(project, "Running Infracost", false), Runnable {
) : Backgroundable(project, "Running Infracost", false), Runnable {
override fun run(indicator: ProgressIndicator) {
this.run()
}


override fun run() {
if (!ensureBinaryAvailable()) {
InfracostNotificationGroup.notifyError(project, "Infracost binary not found")
return
}

val infracostConfigPath = Paths.get(project.basePath, "infracost.yml")
val infracostConfigTemplathPath = Paths.get(project.basePath, "infracost.yml.tmpl")
val infracostUsageFilePath = Paths.get(project.basePath, "infracost-usage.yml")


val commandParts: MutableList<String?> = ArrayList()
commandParts.add(binaryFile)
commandParts.add(InfracostBinary.binaryFile)
commandParts.add("breakdown")
commandParts.add("--format=json")
commandParts.add(String.format("--out-file=%s", resultFile.absolutePath))
Expand All @@ -52,27 +47,21 @@ internal class InfracostBackgroundRunTask(
}
}

val commandLine =
GeneralCommandLine(commandParts)
.withEnvironment(
mapOf(
"INFRACOST_CLI_PLATFORM" to "jetbrains",
"INFRACOST_SKIP_UPDATE_CHECK" to "true",
"INFRACOST_GRAPH_EVALUATOR" to "true",
"INFRACOST_NO_COLOR" to "true"
)
)

commandLine.setWorkDirectory(project.basePath)
val command = ProcessBuilder(commandParts)
command.environment().set("INFRACOST_CLI_PLATFORM", "jetbrains")
command.environment().set("INFRACOST_SKIP_UPDATE_CHECK", "true")
command.environment().set("INFRACOST_GRAPH_EVALUATOR", "true")
command.environment().set("INFRACOST_NO_COLOR", "true")
command.directory(File(project.basePath.toString()))
val process: Process
try {
process = commandLine.createProcess()
process = command.start()
} catch (e: ExecutionException) {
InfracostNotificationGroup.notifyError(project, e.localizedMessage)
return
}

val handler = OSProcessHandler(process, commandLine.commandLineString)
val handler = OSProcessHandler(process, command.toString())
try {
ScriptRunnerUtil.getProcessOutput(
handler, ScriptRunnerUtil.STDOUT_OR_STDERR_OUTPUT_KEY_FILTER, 100000000
Expand Down
Loading

0 comments on commit 8712a3c

Please sign in to comment.