( root: AbsPath, subdir: RelPath, fileName: string )
| 638 | } |
| 639 | |
| 640 | async function maybeLoadRequirementsTxt( |
| 641 | root: AbsPath, |
| 642 | subdir: RelPath, |
| 643 | fileName: string |
| 644 | ): Promise<PythonManifest | null> { |
| 645 | const requirementsTxtRelPath = path.join(subdir, fileName); |
| 646 | const requirementsTxtPath = path.join(root, requirementsTxtRelPath); |
| 647 | const requirementsContent: string | null = |
| 648 | await readFileTextIfExists(requirementsTxtPath); |
| 649 | |
| 650 | if (requirementsContent == null) { |
| 651 | return null; |
| 652 | } |
| 653 | |
| 654 | try { |
| 655 | const pyproject = await convertRequirementsToPyprojectToml( |
| 656 | requirementsContent, |
| 657 | { |
| 658 | workingDir: path.join(root, subdir), |
| 659 | packageRoot: root, |
| 660 | } |
| 661 | ); |
| 662 | |
| 663 | return { |
| 664 | path: requirementsTxtRelPath, |
| 665 | data: pyproject, |
| 666 | origin: { |
| 667 | kind: PythonManifestConvertedKind.RequirementsTxt, |
| 668 | path: requirementsTxtRelPath, |
| 669 | }, |
| 670 | }; |
| 671 | } catch (error: unknown) { |
| 672 | if (error instanceof PythonAnalysisError) { |
| 673 | error.path = requirementsTxtRelPath; |
| 674 | if (!error.fileContent) { |
| 675 | error.fileContent = requirementsContent; |
| 676 | } |
| 677 | throw error; |
| 678 | } |
| 679 | throw new PythonAnalysisError({ |
| 680 | message: `could not parse ${fileName}: ${error instanceof Error ? error.message : String(error)}`, |
| 681 | code: 'PYTHON_REQUIREMENTS_PARSE_ERROR', |
| 682 | path: requirementsTxtRelPath, |
| 683 | fileContent: requirementsContent, |
| 684 | }); |
| 685 | } |
| 686 | } |
| 687 | |
| 688 | async function loadPythonConfigs( |
| 689 | root: AbsPath, |
no test coverage detected