Hello! My name is Brage. I'm a software developer ...
# welcome
k
Hello! My name is Brage. I'm a software developer from Norway living in Finland. I work for a small web agency called Bjerk. I've just started using pants and am trying to author my own in-repo plugin and I find it quite daunting, to be honest šŸ˜…
šŸ‘‹ 3
b
Welcome! I'm sorry you're struggling with writing a plugin. @fresh-cat-90827 has been working on a tutorial about that. Perhaps it can be helpful? Please do feel free to pepper us with questions in #general, #plugins, etc. We appreciate questions and try to be a friendly and responsive community for newcomers.
f
hey Brage and welcome! There are a few tutorials that may help you getting started. They are going to be published on a website, but in the meanwhile, you can read the markdown: https://github.com/pantsbuild/pants/tree/main/docs/markdown/Tutorials
šŸ‘ 1
w
Also, I wrote these a while back - with corresponding Git repos: https://sureshjoshi.com/development/first-pants-plugin (On a slightly earlier version of Pants)
šŸ™Œ 1
k
I've been following that tutorial, @wide-midnight-78598. Thanks for that! Still wrapping my head around these concepts, though.
b
Anything in particuiar stand out as confusing? It'd be helpful for us to hear what needs more explanation. We'd love to make it easier for folks like you to get started.
w
@kind-angle-20894 Similar to what Carina said, any recommendations, or anything to help grok plugins would be great. I've got some ideas for improvements to the user experience, but at some level - there is just a certain amount of retained knowledge we have that makes it hard to go back to being a new user
k
All I knew coming into this was that pants is a build system that lets you handle all sorts of stuff related to building your software in a more sophisticated way than merely slapping together a bunch of commands using
&&
.
I'm not from the Python world, but I know some basic aspects of python syntax.
One challenge I faced was getting VSCode to play nice with pants.
I was getting help from IntelliSense in impporting stuff from my own .py files, but I couldn't resolve the pants imports. Frustratingly, everything actually working when I ran
./pants list package
(from @wide-midnight-78598’s tutorial), but Pylance was complaining that it could not resolve any of the pants modules.
I ended up figuring it out eventually, and this was the trick, which I wrote down in a little readme for my team: In order to get VSCode's IntelliSense to play nice with python, do these steps: 1. Export pants (whatever this means, I'm not sure)
Copy code
./pants export ::
2. select the virtualenv (may not be necessary?)
Copy code
source dist/export/python/virtualenv/3.9.16/bin/activate
3. Open a python file so that VSCode says "Python" in the bottom blue bar 4. Click "select interpreter" in the bottom of VSCode's GUI. 5. Select "browse file system" 6. Navigate to and select
dist/export/python/3.9.16/__main.py__
Your python files should now have working IntelliSense
That aside, I am generally struggling to understand the concepts of pants and pants plugins. I've started methodically writing my own documentation explaining individual concepts such as goals, targets, rules, dependencies, etc.I'm slowly working my way towards understanding what they mean on an abstract level, but I honestly feel super lost when it comes to actually implementing something useful. Making a rule that does nothing or converts an int to a string is fair enough, but I have no clue what return types or input types I should use if I want to perform an operation on a file.
Copy code
@rule
async def run_my_plugin(???) -> ????:
f
thanks for being verbose and sharing, this is very helpful. I think you may benefit from going through the first tutorial https://github.com/pantsbuild/pants/blob/main/docs/markdown/Tutorials/create-a-new-goal.md which explains how rules are written
k
In my mind I don't need to return anything since I want to perform an operation on a file, but somehow I suspect that that is not how this is supposed to work (void function with side effects seems to go against the whole concept of pants)
f
there are two ways one can go - you can try to hack things trying to see how it's done in Pants source code and hack until it works OR you can go from the basics gradually increasing the complexity (but you have the basics sorted). Both ways are legit, it depends on your personality I guess šŸ™‚
k
It took me a while to understand that the target definitions like this:
Copy code
class ProjectVersionTarget(Target):
    alias = "version_file"
    core_fields = (*COMMON_TARGET_FIELDS, SingleSourceField)
    help = "A project version target representing the VERSION file."
Are the basis for these things you put in the BUILD file:
Copy code
version_file(
    name="blabla"
)
f
right, you may want to take a look at https://www.pantsbuild.org/docs/target-api-concepts
k
I suspect all this would be a bit easier if I was used to Python to begin with, but still I feel like I am in a realm where every single concept is unique and novel since I haven't worked with a sophisticated build system before.
f
I totally get it! It's not trivial per se, and now you have a new language and the paradigms
k
or, I should perhaps qualify that statement: I have worked with build systems, but they have come prepackaged and hidden behind simple JSON configs and single commands such as
tsc
and
node
šŸ‘ 1
Converting typescript to runnable javascript is essentially voodoo magic for all I know
f
but I'd suggest going through the tutorials, they will help you get started. And go through all the pages in the help https://www.pantsbuild.org/docs/plugins-overview helped me a lot. But I think starting with tutorials and going through them even if you don't understand everything would be helpful and you can then revisit the docs as they will suddenly make more sense
šŸ‘ 1
b
If you've be comfortable sharing those personal notes on your interpretation of Pants concepts, I'm sure someone would be willing to take a look and confirm whether you've gotten everything right. Being able to see it expressed in a newbie's words might also give us a better way of phrasing things for other newbies. As @wide-midnight-78598 noted, the maintainers are cursed with an excess of knowledge about the system, making it difficult to recognize when too much has been assumed. It's certainly not what we intend, but is an unfortunate inevitability of being so immersed in the details.
k
I'll happily do so. Here's what I have so far:
Copy code
**Goal**
A goal is a command that pants runs, such as `lint`, `fmt` (format) and so on.

Building a docker image is done with the `package` goal.

**Target**
A target is a set of metadata to describe some code.

Here is our docker image target described in the `packages/backend/BUILD` file:
```BUILD
docker_image(
    name="docker",
)
The target consists of fields. Currently there is only one The command for building our docker image looks like this:
Copy code
sh
./pants package packages/backend:docker
A breakdown of this command: -
package
is the goal -
packages/backend:docker
is the target address of our target, comprised of two parts: -
packages/backend
is the path to the directory of our target -
docker
is the
name
field specified in our
docker_image
target, which is defined in the BUILD file. TODO Rule Dependency **core_fields**```
One thing I have found a bit confusing: What is a target? Is it something that looks like this:
Copy code
class ProjectVersionTarget(Target):
    alias = "version_file"
    core_fields = (*COMMON_TARGET_FIELDS, SingleSourceField)
    help = "A project version target representing the VERSION file."
(in a plugin's python code) or this?
Copy code
version_file(
    name="hello_there"
    source="some/file/path"
)
(in a BUILD file) At this point in time I am led to think that the latter is the target and the former is the target definition. But maybe the former is the target and the latter is instead a "target call" or a "target configuration"?
There's also this thing
Copy code
def target_types():
    return []
I don't exactly comprehend why this is an array. I guess one plugin can contain a bunch of different targets that are completely different features within that plugin? That makes sense, but to me this wasn't obvious from the get go, since I want to make a simple plugin that does one thing (and I could make it do many different things with different fields and rules anyway?).