Skip to content

Commit 8712a3c

Browse files
authored
feat: Switch to download binary on startup (#12)
- 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">
1 parent 26ce56a commit 8712a3c

File tree

18 files changed

+369
-261
lines changed

18 files changed

+369
-261
lines changed

.github/workflows/publish.yml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ jobs:
1919
build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
2020
build-scan-terms-of-use-agree: "yes"
2121

22-
- name: Download latest Infracost
23-
run: ./scripts/download.sh
24-
2522
- name: Run build plugin
2623
run: ./gradlew buildPlugin
2724

CHANGELOG.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,44 @@
44

55
## [Unreleased]
66

7+
## [1.2.0] - 2024-07-09
8+
9+
### Changed
10+
11+
- Download the latest Infracost binary on plugin rather than bundling it
12+
713
## [1.1.1] - 2024-07-04
14+
815
### Fixed
16+
917
- Limit subsequent runs to one queued run, this handles large scale saves and button mashing
1018

1119
### Changed
20+
1221
- Set the platform identifier to jetbrains
1322

1423
## [1.1.0] - 2024-07-02
24+
1525
### Added
26+
1627
- Support for config files
1728
- Support for usage files
1829

1930
## [1.0.2] - 2024-07-01
31+
2032
### Fixed
33+
2134
- Update linux binaries path
2235
- Make the "connect to Infracost" link more simple
2336

2437
## [1.0.1] - 2024-07-01
38+
2539
### Fixed
40+
2641
- Updates to readme
2742

2843
## [1.0.0] - 2024-06-29
44+
2945
### Added
46+
3047
- Initial release of the Infracost plugin for JetBrains IDEs.

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@
99
## Description
1010

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

14-
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.
15+
Infracost is a companion to the [Infracost CLI](https://www.infracost.io/docs/integrations/ci-cd) and provides a way to
16+
view cost estimates directly in your IDE.
1517
<!-- Plugin description end -->
1618

1719
## Features
@@ -30,4 +32,6 @@ You can install the plugin from the JetBrains Plugin Repository.
3032
4. Restart the IDE
3133
5. Open a Terraform file and click on the `Infracost` tab at the bottom of the IDE
3234
6. Click on `Refresh` to get the cost estimate
33-
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.
35+
7. Use our ![CI/CD integrations](https://www.infracost.io/docs/integrations/cicd/) to add cost estimates to pull
36+
requests. This provides your team with a safety net as people can understand cloud costs upfront, and discuss them as
37+
part of your workflow.

build.gradle.kts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ repositories {
2424
}
2525

2626
dependencies {
27+
implementation("org.apache.commons:commons-compress:1.21")
2728
}
2829

2930
kotlin {
@@ -82,10 +83,10 @@ tasks {
8283
changeNotes = properties("pluginVersion").map { pluginVersion ->
8384
with(changelog) {
8485
renderItem(
85-
(getOrNull(pluginVersion) ?: getUnreleased())
86-
.withHeader(false)
87-
.withEmptySections(false),
88-
Changelog.OutputType.HTML,
86+
(getOrNull(pluginVersion) ?: getUnreleased())
87+
.withHeader(false)
88+
.withEmptySections(false),
89+
Changelog.OutputType.HTML,
8990
)
9091
}
9192
}
@@ -109,6 +110,9 @@ tasks {
109110
publishPlugin {
110111
dependsOn("patchChangelog", "signPlugin")
111112
token = environment("PUBLISH_TOKEN")
112-
channels = properties("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) }
113+
channels = properties("pluginVersion").map {
114+
listOf(
115+
it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" })
116+
}
113117
}
114118
}

gradle.properties

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
# IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html
2-
3-
pluginGroup = io.infracost.plugins
4-
pluginName = Infracost
5-
pluginRepositoryUrl = https://github.com/infracost/jetbrains-infracost
6-
pluginVersion = 1.1.1
7-
8-
pluginSinceBuild = 232
9-
pluginUntilBuild = 242.*
10-
11-
platformType = IC
12-
platformVersion = 2023.2.7
13-
platformPlugins =
14-
gradleVersion = 8.8
15-
kotlin.stdlib.default.dependency = false
16-
org.gradle.configuration-cache = true
17-
org.gradle.caching = true
2+
pluginGroup=io.infracost.plugins
3+
pluginName=Infracost
4+
pluginRepositoryUrl=https://github.com/infracost/jetbrains-infracost
5+
pluginVersion=1.2.0
6+
pluginSinceBuild=232
7+
pluginUntilBuild=242.*
8+
platformType=IC
9+
platformVersion=2023.2.7
10+
platformPlugins=
11+
gradleVersion=8.8
12+
kotlin.stdlib.default.dependency=false
13+
org.gradle.configuration-cache=true
14+
org.gradle.caching=true

scripts/download.sh

Lines changed: 0 additions & 70 deletions
This file was deleted.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.infracost.plugins.infracost.actions
2+
3+
import com.intellij.openapi.actionSystem.AnAction
4+
import com.intellij.openapi.actionSystem.AnActionEvent
5+
import com.intellij.openapi.application.ApplicationManager
6+
import com.intellij.openapi.progress.ProgressManager
7+
import com.intellij.openapi.project.Project
8+
import io.infracost.plugins.infracost.actions.tasks.InfracostDownloadBinaryTask
9+
import javax.swing.SwingUtilities
10+
11+
class DownloadInfracostAction : AnAction() {
12+
13+
override fun actionPerformed(e: AnActionEvent) {
14+
ProgressManager.getInstance().run(InfracostDownloadBinaryTask(e.project!!, false))
15+
}
16+
17+
companion object {
18+
fun runDownload(project: Project, initial: Boolean = false) {
19+
val runner =
20+
InfracostDownloadBinaryTask(project, initial)
21+
if (SwingUtilities.isEventDispatchThread()) {
22+
ProgressManager.getInstance().run(runner)
23+
} else {
24+
ApplicationManager.getApplication().invokeLater(runner)
25+
}
26+
}
27+
}
28+
}

src/main/kotlin/io/infracost/plugins/infracost/actions/RunInfracostAction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ class RunInfracostAction : AnAction() {
6464
}
6565

6666
if (running.get()) {
67-
// If a run is already in progress, queue the next run
68-
next.set(runner)
67+
// If a run is already in progress, queue the next run if not already queued
68+
next.compareAndSet(null, runner)
6969
return
7070
}
7171

src/main/kotlin/io/infracost/plugins/infracost/actions/tasks/InfracostAuthRunTask.kt

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package io.infracost.plugins.infracost.actions.tasks
22

33
import com.intellij.execution.ExecutionException
4-
import com.intellij.execution.configurations.GeneralCommandLine
54
import com.intellij.openapi.application.ApplicationManager
65
import com.intellij.openapi.progress.ProgressIndicator
6+
import com.intellij.openapi.progress.Task.Backgroundable
77
import com.intellij.openapi.project.Project
88
import io.infracost.plugins.infracost.actions.CheckAuthAction
9+
import io.infracost.plugins.infracost.binary.InfracostBinary
910
import io.infracost.plugins.infracost.ui.notify.InfracostNotificationGroup
1011
import java.io.BufferedReader
1112
import java.io.InputStreamReader
@@ -15,36 +16,27 @@ import javax.swing.SwingUtilities
1516
internal class InfracostAuthRunTask(
1617
private val project: Project,
1718
private val callback: Consumer<Boolean>
18-
) : InfracostTask(project, "Authenticate Infracost", false), Runnable {
19+
) : Backgroundable(project, "Authenticate Infracost", false), Runnable {
1920
override fun run(indicator: ProgressIndicator) {
2021
this.run()
2122
}
2223

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

29-
val commandParams: MutableList<String?> = ArrayList()
30-
commandParams.add(binaryFile)
31-
commandParams.add("auth")
32-
commandParams.add("login")
30+
val command = ProcessBuilder(commandParts)
31+
command.environment().set("INFRACOST_CLI_PLATFORM", "jetbrains")
32+
command.environment().set("INFRACOST_SKIP_UPDATE_CHECK", "true")
33+
command.environment().set("INFRACOST_GRAPH_EVALUATOR", "true")
34+
command.environment().set("INFRACOST_NO_COLOR", "true")
3335

34-
val commandLine =
35-
GeneralCommandLine(commandParams)
36-
.withEnvironment(
37-
mapOf(
38-
"INFRACOST_SKIP_UPDATE_CHECK" to "true",
39-
"INFRACOST_GRAPH_EVALUATOR" to "true",
40-
"INFRACOST_NO_COLOR" to "true",
41-
"INFRACOST_CLI_PLATFORM" to "jetbrains",
42-
)
43-
)
4436
ApplicationManager.getApplication().executeOnPooledThread {
4537
try {
4638
try {
47-
val process = Runtime.getRuntime().exec(commandLine.commandLineString)
39+
val process = command.start()
4840
val inputReader = BufferedReader(InputStreamReader(process.inputStream))
4941
val inputThread = Thread {
5042
try {

src/main/kotlin/io/infracost/plugins/infracost/actions/tasks/InfracostBackgroundRunTask.kt

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package io.infracost.plugins.infracost.actions.tasks
22

33
import com.intellij.execution.ExecutionException
4-
import com.intellij.execution.configurations.GeneralCommandLine
54
import com.intellij.execution.process.OSProcessHandler
65
import com.intellij.execution.process.ScriptRunnerUtil
76
import com.intellij.openapi.progress.ProgressIndicator
7+
import com.intellij.openapi.progress.Task.Backgroundable
88
import com.intellij.openapi.project.Project
9+
import io.infracost.plugins.infracost.binary.InfracostBinary
910
import io.infracost.plugins.infracost.ui.notify.InfracostNotificationGroup
1011
import java.io.File
1112
import java.nio.file.Paths
@@ -16,25 +17,19 @@ internal class InfracostBackgroundRunTask(
1617
private val project: Project,
1718
private val resultFile: File,
1819
private val callback: BiConsumer<Project, File>
19-
) : InfracostTask(project, "Running Infracost", false), Runnable {
20+
) : Backgroundable(project, "Running Infracost", false), Runnable {
2021
override fun run(indicator: ProgressIndicator) {
2122
this.run()
2223
}
2324

2425

2526
override fun run() {
26-
if (!ensureBinaryAvailable()) {
27-
InfracostNotificationGroup.notifyError(project, "Infracost binary not found")
28-
return
29-
}
30-
3127
val infracostConfigPath = Paths.get(project.basePath, "infracost.yml")
3228
val infracostConfigTemplathPath = Paths.get(project.basePath, "infracost.yml.tmpl")
3329
val infracostUsageFilePath = Paths.get(project.basePath, "infracost-usage.yml")
3430

35-
3631
val commandParts: MutableList<String?> = ArrayList()
37-
commandParts.add(binaryFile)
32+
commandParts.add(InfracostBinary.binaryFile)
3833
commandParts.add("breakdown")
3934
commandParts.add("--format=json")
4035
commandParts.add(String.format("--out-file=%s", resultFile.absolutePath))
@@ -52,27 +47,21 @@ internal class InfracostBackgroundRunTask(
5247
}
5348
}
5449

55-
val commandLine =
56-
GeneralCommandLine(commandParts)
57-
.withEnvironment(
58-
mapOf(
59-
"INFRACOST_CLI_PLATFORM" to "jetbrains",
60-
"INFRACOST_SKIP_UPDATE_CHECK" to "true",
61-
"INFRACOST_GRAPH_EVALUATOR" to "true",
62-
"INFRACOST_NO_COLOR" to "true"
63-
)
64-
)
65-
66-
commandLine.setWorkDirectory(project.basePath)
50+
val command = ProcessBuilder(commandParts)
51+
command.environment().set("INFRACOST_CLI_PLATFORM", "jetbrains")
52+
command.environment().set("INFRACOST_SKIP_UPDATE_CHECK", "true")
53+
command.environment().set("INFRACOST_GRAPH_EVALUATOR", "true")
54+
command.environment().set("INFRACOST_NO_COLOR", "true")
55+
command.directory(File(project.basePath.toString()))
6756
val process: Process
6857
try {
69-
process = commandLine.createProcess()
58+
process = command.start()
7059
} catch (e: ExecutionException) {
7160
InfracostNotificationGroup.notifyError(project, e.localizedMessage)
7261
return
7362
}
7463

75-
val handler = OSProcessHandler(process, commandLine.commandLineString)
64+
val handler = OSProcessHandler(process, command.toString())
7665
try {
7766
ScriptRunnerUtil.getProcessOutput(
7867
handler, ScriptRunnerUtil.STDOUT_OR_STDERR_OUTPUT_KEY_FILTER, 100000000

0 commit comments

Comments
 (0)