-
Notifications
You must be signed in to change notification settings - Fork 334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tasks #1362
Comments
That looks useful. Would it also be intended for devenv inner workings? For instance when requirements.txt changes, run pip install in 'enterShell' when |
Yeah exactly, I hope that a lot of the "state changed, let's do work" can be captured under this abstraction so that we can do better logging and composability. |
One possible design sketch with more explicit naming (I've never really liked 'task' for this): { ... }: {
converge.constraints.add "bundler" {
impl = "bundle-impl.rb";
depends = [];
};
converge.constraints.add "db-migrations" {
satisfied = "bin/check-db";
satisfy = "bundle exec rake db:migrate";
depends = [ converge.constraints.bundler ];
};
converge.goal = [ converge.constraints.db-migrations ];
} This could generate some file like... # converge.json
{
"default": ["db-migrations"],
"constraints": {
"bundler": {
"impl": "bundle-impl.rb",
},
"db-migrations": {
"satisfied": "bin/check-db",
"satisfy": "bundle exec rake db:migrate",
"depends": ["bundler"],
}
}
} And we could have a tool invoked like |
I earlier mentioned a case I was stuck on where i wanted to make changes to the guest user and password and other configurations in rabbitmq that's not available as config arguments but have to be set via the command line, but I couldn't find a way of doing this within the same rabbitmq process or calling a script within devenv.sh that runs for that particular service alone, in this case rabbitmq |
Hmm, I hadn't used Just before, but it seems it cannot handle file dependencies. See casey/just#867. This makes it less useful for cases like running pip when requirements.txt has changed. |
This mixes the dependency graph structure ( In the ideal case, IMO, it'd be an improvement to understand the DAG as some kind of "program". Both If it's not possible to represent this expression as a complete "program", then it's just Perhaps the way out of this would be if the Something like:
|
The example exactly addresses a need I have. Nice. I have a process, |
Aside: I saw a super neat looking progress indicator for tasks in some video covering the latest Zig release: https://youtu.be/_rcD_V1oPus?t=225 / https://asciinema.org/a/661404 There's a blog post specifically covering the implementation of that here: https://andrewkelley.me/post/zig-new-cli-progress-bar-explained.html he calls it "The Zig Progress Protocol Specification". |
It could be worth looking at https://cuelang.org/ to meet the requirements described here Here is an example The below is pseudocode example of creating schemas to define tasks in cue, and a generalized runner for the tasks package main
import (
"encoding/yaml"
"encoding/json"
)
// Load YAML file
yamlData: yaml.Unmarshal(#readFile) & #TaggedFile
#TaggedFile: {
#readFile: string
if #readFile == _|_ {
!!! "Cannot read YAML file"
}
}
// Task schema
#Task: {
name: string
cmd: string | [...string]
deps?: [...string]
check?: [...string]
env?: [string]: string
}
// Validate tasks against schema
tasks: [string]: #Task
tasks: yamlData.tasks
// Add any additional validations or derived fields here
tasks: [string]: {
// Example: Ensure all task names are capitalized
name: =~"^[A-Z]"
}
// Command to output the task graph as JSON
command: output: {
task: json.Marshal(tasks)
stdout: task
} This is an example of a yaml file cue can consume (could be json or other format too) tasks:
setup:
name: "Setup Environment"
cmd: ["./setup_script.sh"]
build:
name: "Build Project"
cmd: ["make", "build"]
deps: ["setup"]
test:
name: "Run Tests"
cmd: ["make", "test"]
deps: ["build"]
check: ["test", "-f", "some_file"]
deploy:
name: "Deploy"
cmd: ["./deploy.sh"]
deps: ["test"]
env:
DEPLOY_ENV: "production" This can be run with a Rust or Go program, output task graph, and run in parallel (pseudo Go example but could be Rust too of course) package main
import (
"encoding/json"
"fmt"
"os/exec"
"sync"
)
type Task struct {
Name string `json:"name"`
Cmd []string `json:"cmd"`
Deps []string `json:"deps,omitempty"`
Check []string `json:"check,omitempty"`
Env map[string]string `json:"env,omitempty"`
}
func main() {
// Run CUE to get task graph
cueCmd := exec.Command("cue", "cmd", "-t", "#readFile=./tasks.yaml", "output")
output, err := cueCmd.Output()
if err != nil {
fmt.Println("Error running CUE:", err)
return
}
var tasks map[string]Task
err = json.Unmarshal(output, &tasks)
if err != nil {
fmt.Println("Error parsing JSON:", err)
return
}
// Execute tasks
var wg sync.WaitGroup
for name, task := range tasks {
wg.Add(1)
go func(name string, task Task) {
defer wg.Done()
executeTask(name, task, tasks)
}(name, task)
}
wg.Wait()
}
func executeTask(name string, task Task, allTasks map[string]Task) {
// Wait for dependencies
for _, dep := range task.Deps {
<-taskCompletionChannels[dep]
}
// Execute task
fmt.Printf("Executing task: %s\n", name)
cmd := exec.Command(task.Cmd[0], task.Cmd[1:]...)
cmd.Env = append(cmd.Env, formatEnv(task.Env)...)
err := cmd.Run()
if err != nil {
fmt.Printf("Error executing task %s: %v\n", name, err)
}
// Signal completion
taskCompletionChannels[name] <- true
}
[ ... ] |
Of course it could be possible to just cut cue out of the picture, and consume and run tasks directly in Rust too. But cue can do merging of config and some other things so I thought it worth a consideration. |
I have quite a similar prototype written in Rust! I'll try to wrap it up and it's so liberating to see we've arrived at similar results 🤯 |
Bit of a weird suggestion, but moonrepo/moon is pretty awesome. Sadly they built their own tool, proto, to handle software acquisition; but they are planning to support other tools. Perhaps we don't need to invent anything here and instead collaborate to support Nix? Tagging @milesj as he may be able to share some input or thoughts |
@rawkode that looks super nice, but I'm concerned that it tries to do too much with things like dependency management. There's also https://bob.build/, but it suffers from the same issue. |
https://taskfile.dev/ looks extremely promising! |
Was watching this to get a better understanding of how Just can integrate with Nix: https://youtu.be/wQCV0QgIbuk and a comment recommended the above over Just - for whatever that’s worth. |
I really don’t like working with/writing YAML; could we use Dhall or something and generate the YAML for Task? 👀 |
I've dumped my thoughts what we'd need for devenv.sh at go-task/task#448 (comment) |
We're using Nix to do congruent configuration where possible,
but in non-Nix world we often need to do convergent configuration.
We're using mostly a glue of bash at the moment, in phases like
enterShell
andenterTest
, etc.Problems
Requirements
Syntax
Command
We'll need to find a good tool that we can use under the hood, one such tool
is Justfile see #1320
The text was updated successfully, but these errors were encountered: