Module: Esp::ActiveProject
- Defined in:
- lib/esp/active_project.rb
Overview
Process-scoped state for “which project is the user currently working in” (step 23). Swapped in by ESPresso’s POST /open-project; helpers that need a working-tree root (vcs_root for diff/approve/reject today; more later) consult this before falling back to Esp::ROOT.
Step 22.5 slice 2: also tracks the project’s game id (‘mw` today, future `ob`/`sr`) so the plugin registry knows which Operations module owns each op for the current request. Missing game on a project read defaults to `mw` for backward compat (every pre-rename project is Morrowind).
Stored module-globally rather than per-request because the WEBrick backend is single-tenant per-instance (one ESPresso ↔ one esp serve), so a global is the right shape; the mutex guards against the thread-per-request model racing a concurrent set + read.
Class Method Summary collapse
- .clear! ⇒ Object
- .game ⇒ Object
-
.resolve(params = {}) ⇒ Object
Same precedence as root_for, but with Esp::ROOT as a final fallback.
- .root ⇒ Object
-
.root_for(params) ⇒ Object
Resolve a root for a request: explicit ‘root:` param wins (preserves the diff-panel pattern of “operate on a specific tree even if a project is open”), then the active project, then nil — the caller decides whether to fall back to Esp::ROOT or error.
-
.set(path, game: nil) ⇒ Object
Store a project root + game id.
Class Method Details
.clear! ⇒ Object
43 44 45 46 47 48 |
# File 'lib/esp/active_project.rb', line 43 def clear! @mutex.synchronize do @root = nil @game = nil end end |
.game ⇒ Object
26 27 28 |
# File 'lib/esp/active_project.rb', line 26 def game @mutex.synchronize { @game } end |
.resolve(params = {}) ⇒ Object
Same precedence as root_for, but with Esp::ROOT as a final fallback. This is what every op that needs a root should call — diff/approve/ reject already do (via Esp::Operations#vcs_root); slice 1 of step 23.5 routes the game ops (build, lint, scaffold, …) through it too so ESPresso’s “open project” actually moves where they operate.
66 67 68 |
# File 'lib/esp/active_project.rb', line 66 def resolve(params = {}) root_for(params) || Esp::ROOT end |
.root ⇒ Object
22 23 24 |
# File 'lib/esp/active_project.rb', line 22 def root @mutex.synchronize { @root } end |
.root_for(params) ⇒ Object
Resolve a root for a request: explicit ‘root:` param wins (preserves the diff-panel pattern of “operate on a specific tree even if a project is open”), then the active project, then nil — the caller decides whether to fall back to Esp::ROOT or error.
54 55 56 57 58 59 |
# File 'lib/esp/active_project.rb', line 54 def root_for(params) explicit = params.is_a?(Hash) ? params['root'] : nil return explicit unless explicit.nil? || explicit.to_s.empty? root end |
.set(path, game: nil) ⇒ Object
Store a project root + game id. Returns the normalized path so callers don’t have to expand again. No directory check here —Operations.open_project validates before calling (separation: this module is pure state).
34 35 36 37 38 39 40 41 |
# File 'lib/esp/active_project.rb', line 34 def set(path, game: nil) normalized = File.(path.to_s) @mutex.synchronize do @root = normalized @game = game end normalized end |