hi all! Cross posting from <#C046T6T9U|general> -&...
# plugins
a
hi all! Cross posting from #general -> https://pantsbuild.slack.com/archives/C046T6T9U/p1631695955493700 I want to develop a plugin to replace some of our custom tooling in the monorepo, so any “get started” advice (or examples) would be super useful
w
it should be possible to build a
goal
that does this, yea
it would be feasible for a custom goal to walk the graph formed by invoking
build-dags
a bunch of times
to do that, you would write
@rules
that invoke
build-dags
, and then recurse on the discovered dependencies
in terms of inspiration: one question is whether airflow dags allow cycles: if they don’t, then you should be fine just using
await Get(Targets, Addresses(stuff_discovered_by_running_the_build_dags_tool))
as to including this into
./pants package
: that might also be feasible…? assuming you’ve built the above code to invoke that tool, you can have another
@rule
consume it, and install it as a generator of
files
targets: https://www.pantsbuild.org/docs/plugins-codegen
that would leave you in a situation where you’d have a custom target type (maybe
airflow_library_dag
next to your
pex_binary
which would generate a
files
target
to add a dependency on the custom target type to your `pex_binary`s, you would probably want to declare a macro (maybe named
airflow_binary
) which would always declare both underlying targets at once, and with a dependency between the binary and the dag
a
understood, thanks!
Is it feasible to import a library declared as a dependency of a this new type of target?
w
yes, it should be
you mean have the
airflow_library_dag
type depend on python code…?
a
yup
on the python code of the library itself
I am still quite lost, unfortunately, so I broke the problem in two parts: 1. Generate a YAML file with the list of tasks generated by each of my libraries 2. Put together all the YAML files, run logic and generate a DAG file for airflow However, I am struggling already in 1. What I want is that my
GenerateSourcesRequest
goes from
PythonSources
to
FilesGeneratorTarget
(if I understood correctly). However, in the
rule
I need to import those python sources to run the correct function, get a dictionary and write it to disk. Does this even make sense? I could create a pex on the fly that calls the desired function, but I am not sure if this makes sense.
w
my 
GenerateSourcesRequest
  goes from 
PythonSources
 to 
FilesGeneratorTarget
 (if I understood correctly)
probably from
PythonSources
to
FilesSources
I need to import those python sources to run the correct function, get a dictionary and write it to disk. Does this even make sense?
that’s correct: to get the python sources of your targets, you’d do something like:
Copy code
sources = Get(
        SourceFiles,
        SourceFilesRequest(
            sources_fields=[t.get(Sources) for t in targets],
            for_sources_types=(PythonSources,),
        ),
    )
then, to run a
Process
, you’d do something like https://www.pantsbuild.org/docs/rules-api-process#process
h
What Pants version are you developing against? Some of the names of these fields is in flux, so depends on that
w
you can create a PEX if you need to, but if the files are small, you can also just pull them into memory in your
@rule
using https://www.pantsbuild.org/docs/rules-api-file-system#digestcontents
a
then, to run a 
Process
, you’d do something like https://www.pantsbuild.org/docs/rules-api-process#process
Can I avoid running a process? It’s just importing some python code and executing a function…
h
Does the function do side-effects, like spawning processes or making network requests? How expensive is the function call also?
a
it imports a few things from the package, but no side effects
and it’s a reasonably quick function
h
Cool, then you should be good to run it directly without
Process
. You'll miss out on on-disk caching and only have in-memory memoization via Pantsd (daemon), but if it's a fast function, probably fine. And you avoid overhead of launching processes
a
That’s a good idea then. Looking into
pants.engine
I don’t see how to transform these sources into something importable. Should I just use importlib and the file path?
h
Import which sources? Airflow-dag, your repository's code?
a
my code
h
You can use
DigestContents
to load them in-memory: https://www.pantsbuild.org/docs/rules-api-file-system#digestcontents. It's the engine safe version of
with open(): f.read()
, meaning it has things like file-watching to know when to invalidate all your rules because of changes
a
understood, thanks!
❤️ 1