(
file: DeepnoteFile,
options: AnalysisOptions = {}
)
| 176 | * Returns lint results and the DAG used for analysis. |
| 177 | */ |
| 178 | export async function checkForIssues( |
| 179 | file: DeepnoteFile, |
| 180 | options: AnalysisOptions = {} |
| 181 | ): Promise<{ lint: LintResult; dag: BlockDependencyDag }> { |
| 182 | // Collect all blocks |
| 183 | const allBlocks: DeepnoteBlock[] = [] |
| 184 | const blockMap = new Map<string, BlockInfo>() |
| 185 | |
| 186 | for (const notebook of file.project.notebooks) { |
| 187 | if (options.notebook && notebook.name !== options.notebook) { |
| 188 | continue |
| 189 | } |
| 190 | |
| 191 | for (const block of notebook.blocks) { |
| 192 | allBlocks.push(block) |
| 193 | blockMap.set(block.id, { |
| 194 | id: block.id, |
| 195 | label: getBlockLabel(block), |
| 196 | type: block.type, |
| 197 | notebookName: notebook.name, |
| 198 | sortingKey: block.sortingKey, |
| 199 | }) |
| 200 | } |
| 201 | } |
| 202 | |
| 203 | const issues: LintIssue[] = [] |
| 204 | |
| 205 | // Check for multiple notebooks (suggest splitting) — skip when filtering by notebook |
| 206 | if (!options.notebook) { |
| 207 | const nonInitNotebooks = file.project.notebooks.filter(nb => nb.id !== file.project.initNotebookId) |
| 208 | if (nonInitNotebooks.length > 1) { |
| 209 | issues.push({ |
| 210 | severity: 'warning', |
| 211 | code: 'multi-notebook', |
| 212 | message: `File contains ${nonInitNotebooks.length} non-init notebooks. Consider splitting into separate files using "deepnote split".`, |
| 213 | blockId: '', |
| 214 | blockLabel: 'project', |
| 215 | notebookName: '', |
| 216 | }) |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | // Check for missing integrations (doesn't require DAG) |
| 221 | const { issues: integrationIssues, summary: integrationSummary } = checkMissingIntegrations(allBlocks, blockMap) |
| 222 | issues.push(...integrationIssues) |
| 223 | |
| 224 | // Check for missing inputs (doesn't require DAG) |
| 225 | const { issues: inputIssues, summary: inputSummary } = checkMissingInputs(allBlocks, blockMap) |
| 226 | issues.push(...inputIssues) |
| 227 | |
| 228 | // Analyze DAG for variable issues |
| 229 | let dag: BlockDependencyDag = { nodes: [], edges: [], modulesEdges: [] } |
| 230 | |
| 231 | if (allBlocks.length > 0) { |
| 232 | const dagResult = await getDagForBlocks(allBlocks, { |
| 233 | acceptPartialDAG: true, |
| 234 | pythonInterpreter: options.pythonInterpreter, |
| 235 | }) |
no test coverage detected