#Supporting Context Directories
1 messages ยท Page 1 of 1 (latest)
Hey, you need to add more metadata do function arguments, in particular these two:
DefaultPath(): taking a stringIgnore(): taking a list of strings
In Function.withArg, you have options to pass those values in.
so two attributes?
Ah I see now.
So two attributes as @magic matrix suggests, and when we find them, pass them in here:
/**
* Returns the function with the provided argument
*/
public function withArg(
string $name,
TypeDefId|TypeDef $typeDef,
?string $description = '',
?Json $defaultValue = null,
?string $defaultPath = '',
?array $ignore = null,
): Function_ {
Thank you @polar plank
Yes. Could be a single Argument() attribute, with multiple options, like TypeScript. Python uses different ones because there was already a Doc() for descriptions so it was weird for it to stand outside.
It's simple as that yep, all the work is done on the engine, just add 2 new function parameter metadata and you're good to go:D
@hardy oar I've tried setting up context directories here: https://github.com/dagger/dagger/pull/8411
It either is not quite working, or it is not working in the way I expected it to.
I set a defaultPath on a directory:
public function test(
#[Argument('Run tests from the given source directory')]
#[DefaultPath('../')]
Directory $source,
When I check the help for that function I see this:
--source Directory Run tests from the given source directory [required]
Naturally if I try dagger call test I get an error saying:
Error: required flag(s) "source" not set
@hardy oar I make it optional, like so:
public function test(
#[Argument('Run tests from the given source directory')]
#[DefaultPath('../')]
Directory|null $source,
--source Directory Run tests from the given source directory
But then I get the following:
[ERROR] DaggerModule\PhpSdkDev::base(): Argument #1 ($source) must be of type
Dagger\Directory, null given, called in
You may need to add the WithOptional(true) but the engine should enforce that rather then SDKs.
It possibly does, but currently I've got the PHP SDK set to just specify whether it's optional on everything.
$typeDef = dag()->typeDef()->withOptional($type->nullable)
So I may be overriding the engines behaviour by explicitly setting withOptional(false) when it's not nullable.
That may be part of the issue so thank you for pointing that out. I will have to change that behaviour as well.
But it still doesn't solve the issue of why, even when I enforce it as optional, the DefaultPath isn't used
You need to pass withOptional(true) even if the argument's type is non-null, in case DefaultPath is used.
But it still doesn't solve the issue of why, even when I enforce it as optional, the DefaultPath isn't used
I presume you don't get the chance to see it being used if the argument is being reported as required.
Right so something along the lines of this?
if (type is nullable OR type has DefaultPath) {
set withOptional(true)
}
On my side, I'm forcing the optional if defaultPath is set
// If the argument is a contextual argument, it becomes optional.
if (arg.defaultPath) {
opts.defaultPath = arg.defaultPath
typeDef = typeDef.withOptional(true)
}
But I agree that it should be handled by the engine instead
To be clear, does that mean currently I do need to force it to be optional in these cases?
It's not properly handled in the engine so yep, are you doing the same @polar plank ?
You beat me to it, thank you, I was just about to ask XD
I'll sort out the withOptional feedback for now and see if that gets me anywhere, thank you both for the help ๐
@polar plank I've made a PR for context directory support which is ready for review now
I reviewed your PR, let me know if something isn't clear ๐
Thank you very much, I'll make those changes shortly!
I've made changes based on your feedback. When you have time to re-review please let me know ๐ Thank you
So the issue is in PHP:
If I have an argument like this:
public function myDaggerFunc(Directory $dir)
I cannot give a simple default value like this:
public function myDaggerFunc(Directory $dir = '.')
It would throw a TypeError because a string is not a Directory
So if I wanted to have a default value in the normal way a PHP developer would do it. I would actually have to create a Directory by scratch, without using the dagger client
Unless there's an easy way for me create a context directory as an object?
I'm only elaborating here to see where the misunderstand lies:
Am I not clearly explaining the difficulty in the README or am I not understanding the full capacity of the context directory?
There's no "context directory" object. It's just a normal dagger.Directory at runtime. The defaultPath setting should be an argument in FunctionArgument(defaultPath: '.'). It's metadata. Arguments with a defaultPath should not have a default value. For example, this will return an error:
@function
def my_dagger_func(self, source: Annotated[dagger.Directory, DefaultPath(".")] = DEFAULT_DIRECTORY) -> dagger.Directory:
return source
That is roughly what I expected, I think I'm possibly misunderstanding Tom's feedback.
If you mean https://github.com/dagger/dagger/pull/8411#discussion_r1758609371, Tom is just saying that it's no longer relative to the source directory. It's relative to the root directory. That was a change in v0.12.
Ah! I follow now, thank you very much. I was working on 0.12.7 when i tested the PR and at the time, it was based on the source directory. I've Just tested it again on 0.13 and you are of course, correct. ๐
Thank you for clearing that up, I'll sort the docs out.
Yep, same for Typescript
Yup that's why my first comment was: try with 0.13 first haha
@true sierra @polar plank I've updated it once more. I think I've addressed all feedback. Thank you for the multitude of reviews ๐