summaryrefslogtreecommitdiff
path: root/scripts/check-build-status.js
blob: 37638e72f54ed2dc229548b5002145b10464410d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import fs from 'fs';
import path from 'path';
import os from 'os'; // Import os module

// --- Configuration ---
const cliPackageDir = path.resolve('packages', 'cli'); // Base directory for the CLI package
const buildTimestampPath = path.join(cliPackageDir, 'dist', '.last_build'); // Path to the timestamp file within the CLI package
const sourceDirs = [path.join(cliPackageDir, 'src')]; // Source directory within the CLI package
const filesToWatch = [
  path.join(cliPackageDir, 'package.json'),
  path.join(cliPackageDir, 'tsconfig.json'),
]; // Specific files within the CLI package
const buildDir = path.join(cliPackageDir, 'dist'); // Build output directory within the CLI package
const warningsFilePath = path.join(os.tmpdir(), 'gemini-code-cli-warnings.txt'); // Temp file for warnings
// ---------------------

function getMtime(filePath) {
  try {
    return fs.statSync(filePath).mtimeMs; // Use mtimeMs for higher precision
  } catch (err) {
    if (err.code === 'ENOENT') {
      return null; // File doesn't exist
    }
    console.error(`Error getting stats for ${filePath}:`, err);
    process.exit(1); // Exit on unexpected errors getting stats
  }
}

function findSourceFiles(dir, allFiles = []) {
  const entries = fs.readdirSync(dir, { withFileTypes: true });
  for (const entry of entries) {
    const fullPath = path.join(dir, entry.name);
    // Simple check to avoid recursing into node_modules or build dir itself
    if (
      entry.isDirectory() &&
      entry.name !== 'node_modules' &&
      fullPath !== buildDir
    ) {
      findSourceFiles(fullPath, allFiles);
    } else if (entry.isFile()) {
      allFiles.push(fullPath);
    }
  }
  return allFiles;
}

console.log('Checking build status...');

// Clean up old warnings file before check
try {
  if (fs.existsSync(warningsFilePath)) {
    fs.unlinkSync(warningsFilePath);
  }
} catch (err) {
  console.warn(
    `[Check Script] Warning: Could not delete previous warnings file: ${err.message}`,
  );
}

const buildMtime = getMtime(buildTimestampPath);
if (!buildMtime) {
  // If build is missing, write that as a warning and exit(0) so app can display it
  const errorMessage = `ERROR: Build timestamp file (${path.relative(process.cwd(), buildTimestampPath)}) not found. Run \`npm run build\` first.`;
  console.error(errorMessage); // Still log error here
  try {
    fs.writeFileSync(warningsFilePath, errorMessage);
  } catch (writeErr) {
    console.error(
      `[Check Script] Error writing missing build warning file: ${writeErr.message}`,
    );
  }
  process.exit(0); // Allow app to start and show the error
}

let newerSourceFileFound = false;
const warningMessages = []; // Collect warnings here
const allSourceFiles = [];

// Collect files from specified directories
sourceDirs.forEach((dir) => {
  const dirPath = path.resolve(dir);
  if (fs.existsSync(dirPath)) {
    findSourceFiles(dirPath, allSourceFiles);
  } else {
    console.warn(`Warning: Source directory "${dir}" not found.`);
  }
});

// Add specific files
filesToWatch.forEach((file) => {
  const filePath = path.resolve(file);
  if (fs.existsSync(filePath)) {
    allSourceFiles.push(filePath);
  } else {
    console.warn(`Warning: Watched file "${file}" not found.`);
  }
});

// Check modification times
for (const file of allSourceFiles) {
  const sourceMtime = getMtime(file);
  const relativePath = path.relative(process.cwd(), file);
  const isNewer = sourceMtime && sourceMtime > buildMtime;

  if (isNewer) {
    const warning = `Warning: Source file "${relativePath}" has been modified since the last build.`;
    console.warn(warning); // Keep console warning for script debugging
    warningMessages.push(warning);
    newerSourceFileFound = true;
    // break; // Uncomment to stop checking after the first newer file
  }
}

if (newerSourceFileFound) {
  const finalWarning =
    '\nRun "npm run build" to incorporate changes before starting.';
  warningMessages.push(finalWarning);
  console.warn(finalWarning);

  // Write warnings to the temp file
  try {
    fs.writeFileSync(warningsFilePath, warningMessages.join('\n'));
    // Removed debug log
  } catch (err) {
    console.error(`[Check Script] Error writing warnings file: ${err.message}`);
    // Proceed without writing, app won't show warnings
  }
} else {
  console.log('Build is up-to-date.');
  // Ensure no stale warning file exists if build is ok
  try {
    if (fs.existsSync(warningsFilePath)) {
      fs.unlinkSync(warningsFilePath);
    }
  } catch (err) {
    console.warn(
      `[Check Script] Warning: Could not delete previous warnings file: ${err.message}`,
    );
  }
}

process.exit(0); // Always exit successfully so the app starts