Hey all, Happy New Year. Have a quick question on ...
# general
d
Hey all, Happy New Year. Have a quick question on some of the inner workings of Pants plugins. Is there a way to attach data to a pants target in flight? For example: Let's say I make a new task
run
which operates on a python_library target.
run
is set up to require
publish
, publish does it's magic and produces an artifact, and within
publish
a string is produced that needs to be associated with that particular library target for
run
. Is there a standardized way to make that association, such that it can be accessed on the target when
run
is executed?
a
yes! for v1 tasks, that's the "product" API
which tasks will set up via the
prepare()
and
product_types()
classmethods
let me find an example/tutorial
does that seem to be what you're looking for?
d
Thanks! Perfect. So I understand the product_types and prepare methods somewhat. I'm just not sure how to specifically associate a target with a variable.
a
you can make the data that you register for the product into a dict of
target -> <variable>
and in the publish task you can
self.context.products.register_data('product-key', {})
(with your mapping of
target -> data
instead of
{}
)
and then in the run task you can
mapping = self.context.products.get_data('product-key')
d
Got it, so that would work. And I assume there's a way to access the current target the task is operating on within the product_types class method?
a
not really -- in this case, you would just do:
Copy code
@classmethod
def product_types(cls):
  return super().product_types() + ['my-product-key']
in the publish task
and in the run task:
Copy code
@classmethod
def prepare(cls, options, round_manager):
  super().prepare(options, round_manager)
  round_manager.require_data('my-product-key')
i know this isn't super clear
let me find a code example
d
Hmmmm..... Actually I think I get you. But may need to make my question a bit more clear.
a
ok, here's an example
d
So let's say, in my execute method in a task I do the following psuedocode
^populates and registers an instance of the
ObjectFiles
product in that task
(please post pseudocode, i'm listening!)
d
For all the python_library targets I have, publish them to a remote repository. Each publish returns let's say.... a URL, or hash, or some arbitrary string, associated with that publish. so
for target in targets: result = do_publish(target);
Now I have a result, that is specific to that target, that I want to access in my run task
a
ok
ok so this part is kind of hidden in the task that i linked you
but let me know if this makes it more clear:
d
Alright, sorry on mobile, but will take a look shortly
a
`publish_task.py`:
Copy code
class PublishTask(Task):

  @classmethod
  def product_types(cls):
    return ['publish-info']

  def execute(self):
    results = {}
    for target in self.get_targets():
      results[target] = do_publish(target)
    self.context.products.register_data('publish-info', results)
`run_task.py`:
Copy code
class RunTask(Task):

  @classmethod
  def prepare(cls, options, round_manager):
    super().prepare(options, round_manager)
    round_manager.require_data('publish-info')

  def execute(self):
    publish_info = self.context.products.get_data('publish-info')
    for target in self.get_targets():
      info = publish_info[target]
@damp-quill-59187 let me know if that is more clear
d
Yep, this is super clear, thank you. I wasn't sure if accessing the data in the
run
task using the target as a key would work, but if it does then that gets me where I need to go, thanks for the help