Commit 1baa6a8
feat: add JS workspace discovery and public batch API (guacsec#415)
## Summary
- Add `JsWorkspaceDiscovery` utility for parsing `pnpm-workspace.yaml`
and `package.json` workspaces field to discover member `package.json`
manifests
- Add parent-traversal lock file discovery to
`JavaScriptProviderFactory` so workspace members find the lock file at
the workspace root
- Add `stackAnalysisBatch()` and `stackAnalysisBatchHtml()` to `Api`
interface and `ExhortApi` implementation
- Add `jackson-dataformat-yaml` dependency for YAML parsing
- Add comprehensive test suites for workspace discovery and lock file
walk-up
## Details
`JsWorkspaceDiscovery` is a static utility class that discovers
workspace
member packages by parsing `pnpm-workspace.yaml` (packages array) or
`package.json` (workspaces array/object format). It globs for
`package.json`
files, filters by ignore patterns, and validates each manifest has
`name`
and `version` fields.
`JavaScriptProviderFactory.create()` now walks up parent directories
when
no lock file is found in the manifest directory. This enables workspace
member packages to find the single lock file at the workspace root.
The walk-up stops at workspace root boundaries or git root, and supports
`TRUSTIFY_DA_WORKSPACE_DIR` override.
The batch API methods delegate to the existing `performBatchAnalysis()`
infrastructure, following the same pattern as `imageAnalysis()`. Config
(`TRUSTIFY_DA_CONTINUE_ON_ERROR`) is read from environment internally.
Implements [TC-3863](https://redhat.atlassian.net/browse/TC-3863)
## Test plan
- [x] pnpm-workspace.yaml parsing discovers member packages
- [x] package.json workspaces array and object formats parsed correctly
- [x] Invalid manifests (missing name/version) are skipped
- [x] Ignore patterns filter out matching paths
- [x] Workspace root detection works for both pnpm and npm/yarn
- [x] Lock file found at workspace root via parent walk-up (npm, yarn,
pnpm)
- [x] Walk-up stops at workspace root boundary
- [x] TRUSTIFY_DA_WORKSPACE_DIR override works
- [x] No lock file anywhere throws descriptive error
- [x] Existing tests unaffected (19 new tests, 0 regressions)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[TC-3863]:
https://redhat.atlassian.net/browse/TC-3863?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent c7f761d commit 1baa6a8
23 files changed
Lines changed: 1031 additions & 1 deletion
File tree
- src
- main/java
- io/github/guacsec/trustifyda
- impl
- providers
- javascript/workspace
- utils
- test
- java
- io/github/guacsec/trustifyda/providers
- javascript/workspace
- resources/tst_manifests/workspace
- empty_workspace
- package_json_array
- packages
- lib-a
- lib-b
- package_json_object
- packages/mod-a
- pnpm_workspace
- packages
- pkg-a
- pkg-b
- with_invalid
- packages
- no_name
- no_version
- valid
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
151 | 151 | | |
152 | 152 | | |
153 | 153 | | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
154 | 159 | | |
155 | 160 | | |
156 | 161 | | |
| |||
228 | 233 | | |
229 | 234 | | |
230 | 235 | | |
231 | | - | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
232 | 240 | | |
233 | 241 | | |
234 | 242 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| 22 | + | |
22 | 23 | | |
23 | 24 | | |
24 | 25 | | |
| |||
134 | 135 | | |
135 | 136 | | |
136 | 137 | | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
137 | 163 | | |
Lines changed: 242 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
33 | 35 | | |
| 36 | + | |
34 | 37 | | |
| 38 | + | |
35 | 39 | | |
36 | 40 | | |
37 | 41 | | |
| |||
50 | 54 | | |
51 | 55 | | |
52 | 56 | | |
| 57 | + | |
53 | 58 | | |
| 59 | + | |
54 | 60 | | |
55 | 61 | | |
56 | 62 | | |
| |||
703 | 709 | | |
704 | 710 | | |
705 | 711 | | |
| 712 | + | |
| 713 | + | |
| 714 | + | |
| 715 | + | |
| 716 | + | |
| 717 | + | |
| 718 | + | |
| 719 | + | |
| 720 | + | |
| 721 | + | |
| 722 | + | |
| 723 | + | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
| 727 | + | |
| 728 | + | |
| 729 | + | |
| 730 | + | |
| 731 | + | |
| 732 | + | |
| 733 | + | |
| 734 | + | |
| 735 | + | |
| 736 | + | |
| 737 | + | |
| 738 | + | |
| 739 | + | |
| 740 | + | |
| 741 | + | |
| 742 | + | |
| 743 | + | |
| 744 | + | |
| 745 | + | |
| 746 | + | |
| 747 | + | |
| 748 | + | |
| 749 | + | |
| 750 | + | |
| 751 | + | |
| 752 | + | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
| 844 | + | |
| 845 | + | |
| 846 | + | |
| 847 | + | |
| 848 | + | |
| 849 | + | |
| 850 | + | |
| 851 | + | |
| 852 | + | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
| 857 | + | |
| 858 | + | |
| 859 | + | |
| 860 | + | |
| 861 | + | |
| 862 | + | |
| 863 | + | |
| 864 | + | |
| 865 | + | |
| 866 | + | |
| 867 | + | |
| 868 | + | |
| 869 | + | |
| 870 | + | |
| 871 | + | |
| 872 | + | |
| 873 | + | |
| 874 | + | |
| 875 | + | |
| 876 | + | |
| 877 | + | |
| 878 | + | |
| 879 | + | |
| 880 | + | |
| 881 | + | |
| 882 | + | |
| 883 | + | |
| 884 | + | |
| 885 | + | |
| 886 | + | |
| 887 | + | |
| 888 | + | |
| 889 | + | |
| 890 | + | |
| 891 | + | |
| 892 | + | |
| 893 | + | |
| 894 | + | |
| 895 | + | |
| 896 | + | |
| 897 | + | |
| 898 | + | |
| 899 | + | |
| 900 | + | |
| 901 | + | |
| 902 | + | |
| 903 | + | |
| 904 | + | |
| 905 | + | |
| 906 | + | |
| 907 | + | |
| 908 | + | |
| 909 | + | |
| 910 | + | |
| 911 | + | |
| 912 | + | |
| 913 | + | |
| 914 | + | |
| 915 | + | |
| 916 | + | |
| 917 | + | |
| 918 | + | |
| 919 | + | |
| 920 | + | |
| 921 | + | |
| 922 | + | |
| 923 | + | |
| 924 | + | |
| 925 | + | |
| 926 | + | |
| 927 | + | |
| 928 | + | |
| 929 | + | |
| 930 | + | |
| 931 | + | |
| 932 | + | |
| 933 | + | |
| 934 | + | |
| 935 | + | |
| 936 | + | |
| 937 | + | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
706 | 948 | | |
707 | 949 | | |
708 | 950 | | |
| |||
0 commit comments