validate.js 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env node
  2. const fs = require('fs');
  3. const path = require('path');
  4. const { spawnSync } = require('child_process');
  5. const root = path.resolve(__dirname, '..');
  6. function fail(message) {
  7. console.error(`FAIL ${message}`);
  8. process.exitCode = 1;
  9. }
  10. function ok(message) {
  11. console.log(`OK ${message}`);
  12. }
  13. function checkFile(relativePath) {
  14. const fullPath = path.join(root, relativePath);
  15. if (!fs.existsSync(fullPath)) fail(`missing ${relativePath}`);
  16. else ok(relativePath);
  17. }
  18. function checkJson(relativePath) {
  19. const fullPath = path.join(root, relativePath);
  20. try {
  21. JSON.parse(fs.readFileSync(fullPath, 'utf8'));
  22. ok(`${relativePath} json`);
  23. } catch (error) {
  24. fail(`${relativePath} json: ${error.message}`);
  25. }
  26. }
  27. function checkNode(relativePath) {
  28. const fullPath = path.join(root, relativePath);
  29. const child = spawnSync(process.execPath, ['--check', fullPath], { encoding: 'utf8' });
  30. if (child.status === 0) ok(`${relativePath} syntax`);
  31. else fail(`${relativePath} syntax: ${child.stderr || child.stdout}`);
  32. }
  33. function walk(dir, predicate, result = []) {
  34. for (const name of fs.readdirSync(dir)) {
  35. const fullPath = path.join(dir, name);
  36. const stat = fs.statSync(fullPath);
  37. if (stat.isDirectory()) walk(fullPath, predicate, result);
  38. else if (predicate(fullPath)) result.push(fullPath);
  39. }
  40. return result;
  41. }
  42. [
  43. 'README.md',
  44. 'openclaw-startup.md',
  45. 'skill-package-manifest.json',
  46. 'install.js',
  47. 'memory-templates/industry-trend-profile.json',
  48. 'scripts/industry-trend-runner.js',
  49. 'scripts/industry-trend-report.js',
  50. 'skills/industry-trend-runner/SKILL.md',
  51. 'skills/industry-trend-runner/api-config.json'
  52. ].forEach(checkFile);
  53. [
  54. 'skill-package-manifest.json',
  55. 'memory-templates/industry-trend-profile.json'
  56. ].forEach(checkJson);
  57. walk(path.join(root, 'skills'), file => path.basename(file) === 'api-config.json')
  58. .forEach(file => checkJson(path.relative(root, file)));
  59. walk(path.join(root, 'scripts'), file => file.endsWith('.js'))
  60. .forEach(file => checkNode(path.relative(root, file)));
  61. checkNode('install.js');
  62. if (process.exitCode) process.exit(process.exitCode);