# Pass command line argument to custom task

**URL:** <https://discuss.gradle.org/t/pass-command-line-argument-to-custom-task/43678>\
**Category:** Help/Discuss\
**Created:** [August 17, 2022, 1:48pm UTC](https://discuss.gradle.org/t/pass-command-line-argument-to-custom-task/43678 "2022-08-17T13:48:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![spartanhooah](https://avatars.discourse-cdn.com/v4/letter/s/ecccb3/32.png) [@spartanhooah](https://discuss.gradle.org/u/spartanhooah)\
**Post date:** [August 17, 2022, 1:48pm UTC](https://discuss.gradle.org/t/pass-command-line-argument-to-custom-task/43678/1 "2022-08-17T13:48:21Z")

</div>

I am developing a plugin that contains a single custom task. The task looks for a command-line argument, say `bar`, and uses it to construct an input file name. However, it appears that the task `@TaskAction` method (and possibly the `@InputFile`-annotated fields?) is running before the plugin’s `apply` method. This leads to the `bar` property being null when the task tries to construct the input file name. What is the correct way to achieve my goal?

Example code and usage follows.

```gradle
class FooPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.tasks.register("foo", FooTask) {
            if (project.hasProperty("bar") {
                def targetFileName = "my${bar}.txt"
            }
        }
    }
}

```

```gradle
abstract class FooTask extends DefaultTask {
    @Input
    String bar

    @InputFile
    abstract RegularFileProperty getBarFile()

    @Option(option = "bar")
    void setBar(bar) {
        this.bar = bar
    }

    @TaskAction
    void doFoo() {
        // task logic using the bar variable
    }
}

```

How I’m attempting to run the task:  
`./gradlew foo -Pbar=baz`

---

<div class="post-metadata">

**Author:** ![Chris\_Dore](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/chris_dore/32/7592_2.png) [@Chris\_Dore](https://discuss.gradle.org/u/Chris_Dore)\
**Post date:** [August 18, 2022, 5:45am UTC](https://discuss.gradle.org/t/pass-command-line-argument-to-custom-task/43678/2 "2022-08-18T05:45:03Z")

</div>

`-P` sets the value of a Gradle/project property, not a task option. You want to follow the task name with `--<option> <val>`. For example, `./gradlew foo --bar baz` (`--bar=baz` also works).

You also need to provide a `description` value with `@Option`. For example, `@Option(option="bar", description="this is the bar")`. This description will appear in the task help, `./gradlew help --task foo`.

Here’s how I might approach what you are trying to do

```gradle
abstract class FooTask extends DefaultTask {
    @InputFile
    abstract RegularFileProperty getBarFile()
    @Option(option = "bar", description="blah")
    abstract Property<String> getBar()
    @TaskAction
    void doFoo() {
        println barFile.get().asFile
    }
}
class FooPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.tasks.register("foo", FooTask) {
            barFile.convention(bar.map { barVal ->
                project.layout.projectDirectory.file("my${barVal}.txt")
            })
        }
    }
}

```

---

<div class="post-metadata">

**Author:** ![spartanhooah](https://avatars.discourse-cdn.com/v4/letter/s/ecccb3/32.png) [@spartanhooah](https://discuss.gradle.org/u/spartanhooah)\
**Post date:** [August 18, 2022, 12:33pm UTC](https://discuss.gradle.org/t/pass-command-line-argument-to-custom-task/43678/3 "2022-08-18T12:33:40Z")

</div>

Ok, good to know about how to pass command-line arguments to tasks, thank you. Also, I did have a description, but thought it was optional so left it out of my example.

I do have some questions about your code. Gradle says “Cannot have abstract method FooTask.getBar()”. Should that be a setter?

Second, my real code has two input files (one that has a hard-coded name and the other that’s constructed from the command-line argument) and outputs to a third file. I tried putting this all into the `bar.map` closure, but got a compiler warning:

> ‘convention’ in ‘org.gradle.api.file.RegularFileProperty’ cannot be applied to ‘(org.gradle.api.provider.Provider\<java.lang.Object\>)’
