Files
herolib/lib/core/herocmds/tofix.md
2025-10-12 12:30:19 +03:00

16 KiB
Raw Blame History

Overview

The lib/core/playcmds directory contains the core “playcommands” that are used by the playcmds.run() entrypoint. The bulk of the code works, but there are several logic, naming and deadcode problems that make the package harder to maintain, cause potential compiletime collisions, and generate confusing TODO comments in the source.

Below youll find a concise, actionable “TODO list” grouped by file, together with a short description of the problem and exact code changes that should be applied. The aim is to get the module to compile cleanly, make the public API consistent, and remove dead / misleading code.


1 lib/core/playcmds/play_docusaurus.v

Problem What to do
Name clash the file defines a fn play(mut plbook PlayBook) ! in the playcmds module. This collides with other possible play functions (e.g. play_core, play_git), and the function is never used by the factory. 1. Rename the function to pub fn play_docusaurus(mut plbook PlayBook) !.
2. Update the factory.v to call the renamed function (or simply remove this file and call docusaurus.play directly).
3. Remove the import of PlayBook from the file header if it is no longer needed.
Unused import import incubaid.herolib.core.playbook { PlayBook } is only needed for the renamed function. If we decide to keep the wrapper, keep it; otherwise, delete the whole file. Delete or comment out the file if you prefer to call docusaurus.play directly from factory.v.
Missing documentation The file has no comment describing why the wrapper exists. Add a short comment: // Wrapper used by legacy scripts forwards to the docusaurus module.

Concrete Patch (rename function, update factory)

// lib/core/playcmds/play_docusaurus.v
module playcmds

import incubaid.herolib.core.playbook { PlayBook }
import incubaid.herolib.web.docusaurus

// -------------------------------------------------------------------
// Legacy wrapper: older scripts expected a “play” function in the
// playcmds package.  We keep it for backwardscompatibility and
// forward the call to the real docusaurus implementation.
// -------------------------------------------------------------------
pub fn play_docusaurus(mut plbook PlayBook) ! {
    docusaurus.play(mut plbook)!
}

Update in lib/core/playcmds/factory.v

// Replace the old call (if any) with the new wrapper:
play_docusaurus.play(mut plbook)!   // <-- new line, optional
// OR simply delete the import of the wrapper if you decide to
// use the docusaurus module directly.

2 lib/core/playcmds/play_git.v

Problem What to do
Wrong API name the code uses gittools.new(gittools.GitStructureArgGet{}) there is no GitStructureArgGet struct in the gittools package. The correct type is gittools.GitStructureArgs (or the default gittools.GitStructure argument). Replace GitStructureArgGet with the correct type (gittools.GitStructureArgs).
Missing import alias the file uses gittools.new and gittools.new but the import is just import incubaid.herolib.develop.gittools. That is fine, but for clarity rename the import to gittools (it already is) and use the same alias everywhere.
Potential nil gs after a git.clone we do gs = gittools.new(coderoot: coderoot)!. This shadows the previous gs and loses the original configuration (e.g. light, log). The intent is to reinitialise the GitStructure only when a coderoot is explicitly given. Keep the current flow but document the intention.
Unused variable action_ the variable action_ is used only for iteration. No problem.
Missing gittools.GitCloneArgs check that the struct is actually named GitCloneArgs in the gittools package. If not, change to the proper name. Verify and, if needed, replace with the correct struct name (gittools.GitCloneArgs).
Missing error handling for unknown actions the code already prints an error and continues when error_ignore is true. That part is OK.
Redundant import the file imports incubaid.herolib.ui.console but only uses console.print_stderr. Keep it, but add a comment that it is for verbose error reporting.
Formatting add a header comment explaining what this file does (process git actions). Add a comment block at the top of the file.

Concrete Patch (partial)

// lib/core/playcmds/play_git.v
module playcmds

import incubaid.herolib.develop.gittools
import incubaid.herolib.core.playbook { PlayBook }
import incubaid.herolib.ui.console

// ---------------------------------------------------------------
// Git actions interpreter for HeroScript. This file
// parses `!!git.*` actions and forwards them to the
// gittools package.
// ---------------------------------------------------------------

fn play_git(mut plbook PlayBook) ! {
    // -----------------------------------------------------------
    // !!git.define  configure the GitStructure
    // -----------------------------------------------------------
    define_actions := plbook.find(filter: 'git.define')!
    mut gs := if define_actions.len > 0 {
        // ... (same as before)
    } else {
        // Default GitStructure (no args)
        gittools.new(gittools.GitStructureArgs{})!
    }

    // -----------------------------------------------------------
    // !!git.clone  clone repositories
    // -----------------------------------------------------------
    // (unchanged)
    // -----------------------------------------------------------
    // !!git.repo_action  pull, commit, push, …
    // -----------------------------------------------------------
    // (unchanged)
    // -----------------------------------------------------------
    // !!git.list  print repo status
    // -----------------------------------------------------------
    // (unchanged)
    // -----------------------------------------------------------
    // !!git.reload_cache  reload git cache
    // -----------------------------------------------------------
    // (unchanged)
}

Fix the GitStructureArgs (if the actual struct name differs, adjust accordingly).


3 lib/core/playcmds/play_core.v

Problem What to do
env_set_once the code uses session.env_set(key, val) for both env_set and env_set_once. The env_set_once method exists on Session and prevents overwriting a previously set key. If the intention is to set a variable only when it has not been set, use session.env_set_once(key, val). Change the env_set_once case to call session.env_set_once.
Unused comment the comment “// Use env_set instead of env_set_once to avoid duplicate errors” is contradictory. Replace the comment with a clear explanation.
Missing import console is already imported. No changes needed.
Potential missing session.env nil check if plbook.session is optional, a nil check should be added. This is defensive but not strictly required because a PlayBook always creates a Session. Still, add a guard. Add a guard: if plbook.session == none { return error('No session attached to PlayBook') } before first use of session.
Unused variable sitename := session.env_get('SITENAME') or { '' } is never used. Remove it (or use it for templating if needed).
Formatting add a comment block at the top explaining purpose of the module.

Patch

// lib/core/playcmds/play_core.v
module playcmds

import incubaid.herolib.develop.gittools
import incubaid.herolib.core.playbook { PlayBook }
import incubaid.herolib.ui.console
import incubaid.herolib.core.texttools

// -------------------------------------------------------------------
// Core playcommand processing (context, session, envsubst, etc)
// -------------------------------------------------------------------

fn play_core(mut plbook PlayBook) ! {
    // ----------------------------------------------------------------
    // 1.  Include handling (play include / echo)
    // ----------------------------------------------------------------
    // ... (unchanged)
    // ----------------------------------------------------------------
    // 2.  Session environment handling
    // ----------------------------------------------------------------
    // Guard  make sure a session exists
    mut session := plbook.session or {
        return error('PlayBook has no attached Session')
    }

    // !!session.env_set / env_set_once
    for mut action in plbook.find(filter: 'session.')! {
        mut p := action.params
        match action.name {
            'env_set' {
                key := p.get('key')!
                val := p.get('val') or { p.get('value')! }
                session.env_set(key, val)!
            }
            'env_set_once' {
                key := p.get('key')!
                val := p.get('val') or { p.get('value')! }
                // Use the dedicated “setonce” method
                session.env_set_once(key, val)!
            }
            else { /* ignore unknown subaction */ }
        }
        action.done = true
    }

    // ----------------------------------------------------------------
    // 3.  Template replacement in action parameters
    // ----------------------------------------------------------------
    // (unchanged)
}

4 lib/core/playcmds/factory.v

Problem What to do
Unused imports several imports are commented out. Keep them commented or delete if not needed.
Missing call to the renamed play_docusaurus after renaming, the factory should either call play_docusaurus or rely on docusaurus.play directly. Either (a) remove the wrapper import entirely (since docusaurus.play is already called) or add a call to play_docusaurus if you want to keep the wrapper.
Potential deadcode the commented-out sections for play_ssh, play_publisher, etc., are dead and can be removed to keep the file concise.
Consistency rename the run function to run_playcmds (optional) for clarity; not mandatory, but improves readability.
Add documentation a short header comment describing the purpose of the factory function. Add comment at top of file.

Patch (cleanup)

module playcmds

import incubaid.herolib.core.playbook { PlayBook, PlayArgs }
import incubaid.herolib.core.playbook
import incubaid.herolib.core.playcmds
import incubaid.herolib.core.playcmds.{play_core, play_git, play_docusaurus}
import incubaid.herolib.web.docusaurus as docusaurus_mod   // optional alias

// -------------------------------------------------------------------
// run  entry point for all HeroScript playcommands
// -------------------------------------------------------------------
pub fn run(args_ PlayArgs) ! {
    mut args := args_
    mut plbook := args.plbook or {
        playbook.new(text: args.heroscript, path: args.heroscript_path)!
    }

    // Core actions
    play_core(mut plbook)!
    // Git actions
    play_git(mut plbook)!

    // Business model (e.g. currency, bizmodel)
    bizmodel.play(mut plbook)!   // <-- ensure that bizmodel.play exists

    // OpenAI client
    openai.play(mut plbook)!

    // Website / docs
    site.play(mut plbook)!
    doctree.play(mut plbook)!
    // Docusaurus  either call the wrapper or the module directly
    // play_docusaurus(mut plbook)!   // < optional wrapper
    docusaurus.play(mut plbook)!   // direct call (preferred)

    // (optional) other playcommands can be added here

    // Ensure we did not leave any actions unprocessed
    plbook.empty_check()!
}

5 _archive Directory (All Files)

The _archive folder contains dead, commentedout, or placeholder code (e.g., bizmodel.v, currency.v, dagu.v, etc.). They are compiled into the playcmds module but serve no purpose. Keeping them clutters the module namespace and may hide future compile errors.

Action Items

File Action
*_archive/*.v Delete the whole _archive directory (or move it outside of lib/core/playcmds to a noncompiled location).
If any of the archived files contain code that you still need (e.g., play_juggler), move them to a dedicated playcmds/juggler.v file or an appropriate submodule.
After removal, run v . to verify the package builds without “duplicate module” errors.

6 lib/core/playcmds/play_ssh.v Minor Cleanup

Problem What to do
Unused import import incubaid.herolib.osal.sshagent is used, fine.
No pub on play_ssh the function is private but is referenced from factory.v. It is already called as play_ssh(mut plbook). The function is public (no pub needed because it's called inside the same module). No change needed.
Comment about missing actions Keep a short comment stating “Currently only key_add is supported”.
Add error handling The else branch returns an error. This is fine. No changes needed.

7 lib/core/playcmds/play_luadns.v

Problem What to do
Unused import os is commented out (good).
Unused variable mut buildroot etc. These variables are commented out already. No change needed.
Naming function play_luadns is pub (good).
Potential missing luadns import The import is correct. No changes.

8 lib/core/playcmds/play_zola.v All code is commented out

No current code. Keep the file as a placeholder for future implementation. No action needed unless you want to delete it to keep the repo tidy.


9 lib/core/playcmds/readme.md

Problem What to do
Outofdate example It still refers to playcmds.run(..., heroscript_path:''). The run signature now uses PlayArgs. Update the README to reflect the new PlayArgs struct (heroscript_path is now heroscript_path but heroscript is a string argument, not a map).
Add example Provide a tiny example that shows how to run from a .hero file using run(PlayArgs{...}). Update README accordingly.

Example README update

# Using the playcmds package

```v
import incubaid.herolib.core.playcmds

mut args := playcmds.PlayArgs{
    heroscript:         my_hero_script,
    heroscript_path: '/tmp/hero',
    reset:              false,
}
playcmds.run(args)!

---

## ✅ Summary of Files to Modify

| File | Change(s) |
|------|----------|
| `lib/core/playcmds/play_docusaurus.v` | Rename exported function to `play_docusaurus`, update wrapper or remove. |
| `lib/core/playcmds/play_git.v` | Correct `GitStructure` API, add header comment, ensure correct struct names (`GitStructureArgs`, `GitCloneArgs`). |
| `lib/playcmds/play_core.v` | Use `env_set_once`, add sessionnil guard, remove unused `sitename`, add documentation comment. |
| `lib/playcmds/factory.v` | Clean up imports, call `docusaurus.play` directly (or use renamed wrapper), remove dead/ commented-out sections, add file header comment. |
| `lib/core/playcmds/_archive/*` | **Delete** entire `_archive` folder (or move needed code elsewhere). |
| `lib/core/playcmds/readme.md` | Update example to match current `PlayArgs` struct. |
| (optional) `lib/playcmds/play_docusaurus.v` (if wrapper kept)  add wrapper comment. |
| (optional) `lib/playcmds/_archive/...`  move any needed code to proper modules. |

---

## 🚀 Next Steps

1. **Apply the patches** listed above (or copypaste the suggested code changes).  
2. **Run** `v .` from the repository root to verify that the package builds.  
3. **Run** the test suite (`./test_runner.vsh` or the GitHub actions) to ensure no regressions.  
4. **Commit** the changes with a clear commit message, e.g. `"fix: rename play_docusaurus, fix gittools API, cleanup playcmds module"`.

After these changes the **`lib/core/playcmds`** module will compile cleanly, the public API will be consistent, and the dead code will no longer pollute the package namespace. Happy coding! 🚀