donkirkby / live-py-plugin

Live coding in Python with PyCharm, Emacs, Sublime Text, or even a browser
https://donkirkby.github.io/live-py-plugin
MIT License
290 stars 57 forks source link

Pulumi support #484

Closed iridian-ks closed 1 year ago

iridian-ks commented 1 year ago

What I did

Start a new Pulumi project, open in Emacs, and enable live-mode.

$ mkdir example
$ cd example/
$ export PULUMI_HOME=$(pwd)/.pulumi
$ pulumi login file://$(pwd)
$ pulumi new --force

From here start typing python to get to the Python template and let the rest automatically setup a venv for you.

emacs __main__.py

These commands in spacemacs to enable the venv and start live mode

SPC m v a
# navigate to the venv sub-directory
ENTER
SPC m l

No errors yet but any attempt to use Pulumi will throw an error:

import pulumi
pulumi.get_stack()

What happened

Describe what you saw, probably including the live coding display, like this:

pulumi.errors.RunError : Missing stack name; for test mode, please call `pulumi.runtime.set_mocks` and provide a value for the `stack` argument

What I wanted to happen

I think I need a way to hook into live coding (somehow) so I can call some Python code to put Pulumi in test mode.

try:
  import livecode
  if livecode.active:
    pulumi.runtime.set_mocks(stack="livemode")
except ImportError:
  pass
x = pulumi.get_stack() |  x = "livemode"

My environment

Describe the versions of everything you were using:

donkirkby commented 1 year ago

Would the driver script feature help? You can use another Python script to import and run the script you're editing. Take a look at the Emacs intro and search for the driver description. The driver command should be able to handle most of the same arguments as python.

iridian-ks commented 1 year ago

OK, I'll document here in case someone else from the Pulumi world comes by. There is some slight refactoring that needs to happen to make this work.

Whatever you have in __main__.py needs to move because of import paths as this plugin requires testing to be setup. The docs for setting up tests is documented here: https://www.pulumi.com/docs/guides/testing/unit/

I chose to move everything in __main__.py to app.py inside a run method.

Here is the new __main__.py, which is not tested and can't be live-edited and what Pulumi will execute to run your code.

"""A Python Pulumi program"""
import app
app.run()

Move everything from that file to a new file like app.py

import pulumi
def run():
    stack = pulumi.get_stack()
    pulumi.debug(stack)

Create, in the same directory test_app.py which should look like this

import unittest
from typing import List, Optional, Tuple

import pulumi
from pulumi.runtime import MockCallArgs, MockResourceArgs

class Mocks(pulumi.runtime.Mocks):
    def new_resource(self, args: MockResourceArgs) -> Tuple[Optional[str], dict]:
        return super().new_resource(args)

    def call(self, args: MockCallArgs) -> Tuple[dict, Optional[List[Tuple[str, str]]]]:
        return super().call(args)

pulumi.runtime.set_mocks(
    mocks=Mocks(),
    stack="tests",
)

import app
app.run()

class TestingWithMocks(unittest.TestCase):
    @pulumi.runtime.test
    def test_stack_name(self):
        def check_stack_name(args):
            self.assertEqual(pulumi.get_stack(), args[0], "stack name must be tests")

        return pulumi.Output.all("tests")

When you edit app.py you can do C-c M-d and put -m unittest test_app and you should get this

import pulumi                                                                                                                |
                                                                                                                             |
                                                                                                                             |
def run():                                                                                                                   |stack = 'tests'
    stack = pulumi.get_stack()                                                                                               |
    pulumi.debug(stack)                                                                                                      |

Success!