t32-commit-level-mode.mjs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. // Select this ticket's hunks without altering concurrent worktree/index changes.
  2. import { spawnSync } from 'node:child_process'
  3. import { mkdtempSync, readFileSync } from 'node:fs'
  4. import { tmpdir } from 'node:os'
  5. import { join } from 'node:path'
  6. const paths=['CONTEXT.md','public/cockpit/models/pipes/README.md','tools/pipe-models/README.md',
  7. 'src/modules/cockpit/domain/pipeDiameterDisplay.js','src/modules/cockpit/domain/pipeModels.js','src/modules/cockpit/domain/pipeNetwork.js','src/modules/cockpit/domain/pipeVisual.js','src/modules/cockpit/services/cesiumPipeModels.js',
  8. '.scratch/cockpit-real-data-wayfinding/issues/32-32.md',
  9. ...['t32-adapter-behavior','t32-color-layer','t32-diameter-fill','t32-pipe-model-plan','t32-visibility-style','t32-network-level','t32-pipe-view-mode','t32-view-layer-flow','t32-visual-default','t32-cesium-bundle-loader','t32-use-cesium-bundle','t32-view-live-diagnosis'].map(n=>`.scratch/cockpit-real-data-wayfinding/verify/${n}.mjs`),
  10. '.scratch/cockpit-real-data-wayfinding/verify/artifacts/t32/view-mode-network-level-fix.md',
  11. '.scratch/cockpit-real-data-wayfinding/verify/artifacts/t32/view-mode-live-diagnosis.json']
  12. const shared=['src/modules/cockpit/services/cesiumPipeLayer.js','src/modules/cockpit/services/mapService.js','src/modules/cockpit/components/MapInfoPanel.vue']
  13. function git(args,{input,env=process.env}={}){const r=spawnSync('git',args,{input,env,encoding:'utf8'});if(r.status!==0)throw Error(r.stderr||r.stdout);return r.stdout}
  14. function once(text,a,b){if(text.split(a).length!==2)throw Error('Ambiguous anchor: '+a.slice(0,70));return text.replace(a,b)}
  15. const head=git(['rev-parse','HEAD']).trim(),other=git(['diff','--cached','--name-only']).trim().split('\n').filter(Boolean)
  16. if(other.some(p=>paths.includes(p)||shared.includes(p)))throw Error('Concurrent staged overlap; inspect first')
  17. const env={...process.env,GIT_INDEX_FILE:join(mkdtempSync(join(tmpdir(),'t32-level-index-')),'index')}
  18. git(['read-tree',head],{env});git(['add','--',...paths],{env})
  19. for(const p of shared){
  20. let s=git(['show',head+':'+p]).replace(/\r\n/g,'\n'),current=readFileSync(p,'utf8').replace(/\r\n/g,'\n')
  21. if(p.endsWith('cesiumPipeLayer.js')){
  22. s=once(s,'const layerVersions = new WeakMap()','const layerVersions = new WeakMap()\nconst pipeViewModes = new WeakMap()')
  23. s=once(s,'颜色统一由行业/备注决定','颜色统一由行业/networkLevel决定')
  24. s=once(s,'// Pending/failed objects keep guides; ready pipes retain only distant guides and show close-up volume.','// Ground keeps guides at all distances; only ready pipeline-view models use distant guides.')
  25. s=once(s,'createCesiumPipeModels(viewer, { source, onChange: onModelChange })',"createCesiumPipeModels(viewer, { source, onChange: onModelChange, viewMode:pipeViewModes.get(viewer)||'ground' })")
  26. const start=current.indexOf('/** View state is retained'),end=current.indexOf('/** 引导态/退出驾驶舱',start)
  27. if(start<0||end<start)throw Error('Missing view state interface')
  28. s=once(s,'/** 引导态/退出驾驶舱',current.slice(start,end)+'/** 引导态/退出驾驶舱')
  29. // Preserve existing ticket33 diff work outside this commit. Its fingerprint update stays in worktree.
  30. }else if(p.endsWith('mapService.js')){
  31. s=once(s,'instance.engine.applyViewModeLayers(instance.viewer, instance.tilesetInstances || [], plan)', 'instance.engine.applyViewModeLayers(instance.viewer, instance.tilesetInstances || [], plan)\n instance.pipeLayer?.setPipeViewMode(instance.viewer, plan.mode)')
  32. s=once(s,' record.pipeLayer = engine\n', ' record.pipeLayer = engine\n engine.setPipeViewMode(record.viewer, viewMode)\n')
  33. }else{
  34. const anchor=' · 管径:源数据 {{ pipeModelState.diameterSummary.reported }} 段 / 双侧推算 {{ pipeModelState.diameterSummary.interpolated }} 段 / 未补 {{ pipeModelState.diameterSummary.missing }} 段'
  35. s=once(s,anchor,anchor+'\n · 其中显示默认 {{ pipeModelState.visualDefaultCount || 0 }} 段(源管径仍未知)')
  36. }
  37. const hash=git(['hash-object','-w','--stdin'],{input:s}).trim();git(['update-index','--cacheinfo',`100644,${hash},${p}`],{env})
  38. }
  39. git(['diff','--cached','--check'],{env});console.log(git(['diff','--cached','--stat'],{env}))
  40. if(git(['rev-parse','HEAD']).trim()!==head)throw Error('HEAD changed before commit; retry after review')
  41. console.log(git(['commit','-m','fix(cockpit): keep ground pipe guides and model missing diameters by category (#32)'],{env}))
  42. git(['reset','--quiet','HEAD','--',...paths,...shared])
  43. const after=git(['diff','--cached','--name-only']).trim().split('\n').filter(Boolean)
  44. if(after.join('\n')!==other.join('\n'))throw Error('Concurrent staging changed; inspect')
  45. console.log('Other staged paths preserved:',after.length)