Compare commits

...

164 Commits
v1.9.9 ... main

Author SHA1 Message Date
Abhisek Datta
6acf08aec0
feat: Exclude Fork and Archive during GitHub Org Scan (#650)
* Only scan private repos under org based scan

* Only scan private repos under org based scan

* fix: Style and formatting issues

* Update scan.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com>

* fix: Add tests for github org reader filters

---------

Signed-off-by: Abhisek Datta <abhisek.datta@gmail.com>
Co-authored-by: infosecwonderland <monika.talekar@ascenda.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-09 16:44:49 +00:00
Sahil Bansal
33c4ca5059
Fix CycloneDX SBOM validation (#647)
* fix component duplication & license format

* fix tests

* use bool type for consistency
2025-12-04 09:34:59 +05:30
Sahil Bansal
a430641960
Add bun.lock parser support (#636)
* add bun.lock file parser support

* fix linter and update ListParsers test case

* fix linter
2025-12-01 12:56:48 +05:30
Kunal Singh
76788aa1cb
fix: json matching for mcp publish verify (#645) 2025-12-01 10:46:35 +05:30
Kunal Singh
dbc2eadac3
fix: verify mcp publish job failing (#642)
* fix: verify mcp publish failing

* added comments

* fix typo
2025-11-27 11:21:38 +00:00
Kunal Singh
ecf8c93f3f
Merge pull request #644 from safedep/chore/precommit-fmt-code
chore: Add golangci fmt for pre-commit
2025-11-27 15:11:34 +05:30
abhisek
070c5f5a24
chore: Add golangci fmt for pre-commit 2025-11-27 15:00:10 +05:30
Oleksandr Redko
4e39cebe61
chore: add formatters to golangci-lint config (#643)
Signed-off-by: Oleksandr Redko <oleksandr.red+github@gmail.com>
2025-11-27 14:58:24 +05:30
Kunal Singh
767e7cb16e
fix: OCI packages must not have 'version' field (#641) 2025-11-26 17:28:12 +05:30
Kunal Singh
4da939276e
fix: description validation error, mcp publishing (#640) 2025-11-26 16:32:38 +05:30
Kunal Singh
dc5846fb93
Merge pull request #639 from safedep/fix-mcp-ci-wd
fix: wrong working directory construction in mcp publishing CI
2025-11-26 14:44:35 +05:30
Kunal Singh
18a996dd53 relative path 2025-11-26 14:38:06 +05:30
Kunal Singh
333729a032 fix: path 2025-11-26 14:36:09 +05:30
Kunal Singh
0a67953b3f checkout before anyting 2025-11-26 14:33:02 +05:30
Kunal Singh
3316c81f35 fix: wrong working directory construction 2025-11-26 14:27:41 +05:30
Kunal Singh
51e185a09f
Merge pull request #638 from safedep/fix-mcp-ci
fix: working directory to .mcp-publisher
2025-11-26 14:08:34 +05:30
Kunal Singh
4599bacf17 fix: working directory to .mcp-publisher 2025-11-26 14:01:46 +05:30
Kunal Singh
e971466097
feat: vet-mcp registry publishing (#635)
* feat: ver-mcp registry publishing

* Update .github/workflows/publish-mcp.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>

* feat: verify job for mcp server publish

* feat: refactor server.json location

* fix: cd to .mcp-publisher dir

* update logo urls

* refactor: publish to mcp when container is build

---------

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-26 13:20:34 +05:30
Kunal Singh
65c44c97c1
Merge pull request #634 from safedep/vet-mcp-cursor-download-link-fix
Update cursor installation link for MCP Server
2025-11-24 13:25:39 +05:30
Kunal Singh
1c824c5515
Update cursor installation link for MCP Server
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-11-24 13:04:00 +05:30
Abhisek Datta
e1908e783b
chore: Update SafeDep Cloud URLs (#632)
* fix: SafeDep cloud URLs

* fix: Markdown formatting issue
2025-11-10 06:45:13 +00:00
Kunal Singh
6f5d0cea33
fix: github action versions not pinned and top level permissions missing (#631) 2025-10-25 16:45:58 +05:30
Sahil Bansal
dc3bc11a51
add git in vet image (#629) 2025-10-17 14:35:23 +05:30
Sahil Bansal
9aebb9d68e
fix: Handle Multiple License Type in npm Graph Parser (#625)
* do not fail on non string values for npm graph license field

* add non-string license type package for testing

* fix: Handle multiple cases for npm package-json license

---------

Co-authored-by: abhisek <abhisek.datta@gmail.com>
2025-10-15 09:30:21 +05:30
Abhisek Datta
801e81ac0d
fix: Use standard colors for inspect malware command (#624) 2025-10-13 04:20:06 +00:00
Kunal Singh
aa06dc6d93
feat: using branch color in manual (#623) 2025-10-13 09:06:01 +05:30
Kunal Singh
8e02db1d09
Merge pull request #622 from safedep/refactor/remove-local-manaul-gen
refactor: remove locally generated manual flow
2025-10-11 10:15:41 +05:30
Kunal Singh
6ad8539938 generate vet cli manual in ./docs/manual dir 2025-10-10 22:28:48 +05:30
Kunal Singh
6ade12a5f6 refactor: remove locally generated manual flow 2025-10-10 22:19:26 +05:30
Kunal Singh
521a5a5756
Merge pull request #621 from safedep/fix/gh-pages-ci
fix: github pages CI build jekyll and deploy to new service
2025-10-10 21:53:48 +05:30
Kunal Singh
54bade56e9 fix: build only after safe generation 2025-10-10 21:45:49 +05:30
Kunal Singh
1aecf640aa fix: typo 2025-10-10 21:43:13 +05:30
Kunal Singh
b1738ac35a fix: github pages CI build jekyll and deploy to new service 2025-10-10 21:40:36 +05:30
Kunal Singh
5663b59636
Merge pull request #620 from safedep/fix/gh-pages-ci-ignore-pattern-dir
fix: added ignore pattern for dynamic lines depending on current work…
2025-10-10 21:18:49 +05:30
Kunal Singh
dc14669605 fix: added ignore pattern for dynamic lines depending on current working directory 2025-10-10 21:08:34 +05:30
Kunal Singh
a8cd3a5b08
feat: github pages cli reference manual deploy (#619)
* feat: github pages cli reference manual deploy

* fix: typos

* feat: simplified logic, use gen folder

* fix: comments, typos, grammar

* update: manual home page

* fix: using generated files in ./docs/manual and not in subdir

* update: manual index (home) with vet.html link - more explicit

* refactor: copy changes
2025-10-10 18:56:31 +05:30
Kunal Singh
2d74224fd3
feat: added internal doc generate command (#618)
* feat: added internal doc generate command

* make generate and go mod tidy
2025-10-09 15:51:15 +05:30
Kunal Singh
b4aaf026c9
fix: recommended way os using golangci lint (#615)
* fix: recommended way os using golangci lint

* make generate

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-10-06 15:31:02 +00:00
Kunal Singh
e48452dd05
feat: show manifest relative path in summary report (#613)
* feat: show manifest relative path in summary report

* fix: typos

* fix: using standard color profile

* fix: log message

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-10-06 20:53:04 +05:30
Abhisek Datta
9f55120d2d
fix: Console Color Profiles (#610)
* fix: Color profile for console

* fix: Console color profile for dark mode

* fix: Simplify color profile identification using charm

* docs: Add trade-off comments
2025-10-06 10:22:48 +05:30
Kunal Singh
f88f76a1c5
Merge pull request #611 from safedep/container-e2e
feat: added vet scan container e2e
2025-10-04 13:21:29 +05:30
Kunal Singh
08e8915242 feat: added vet scan container e2e 2025-10-04 13:13:31 +05:30
Copilot
d5a64a4f61
Remove Markdown Builder in Favor of DRY Markdown Builder (#608)
* Initial plan

* Replace local markdown package with dry library version

- Updated dry dependency to v0.0.0-20250916040320-209e39edc57f (latest)
- Replaced imports from pkg/reporter/markdown to dry/reporting/markdown
- Removed local pkg/reporter/markdown directory
- All tests passing, build successful

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-10-02 23:09:48 +05:30
Copilot
8671c25fb5
Fix #606: Refactor NewEvaluator to use Option pattern and add defensive nil checks (#607)
* Initial plan

* Refactor NewEvaluator to use Option pattern and add defensive nil checks

- Implemented Option function type for configuring evaluator
- Added WithIgnoreError option function
- Updated NewEvaluator to accept only name parameter and variadic options
- Updated all usages in pkg/analyzer/filterv2/ and pkg/analyzer/ directories
- Added defensive nil checks for enum constants in EvaluatePackage
- Added comprehensive tests for Option pattern
- All tests pass successfully

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
2025-10-02 12:28:25 +05:30
Abhisek Datta
3eb501c72b
feat: Add Support for Filter v2 - Spec Based Policy Engine (#560)
* feat: Add support for filter v2

* Add filter v2 support

* Add test for filter v2 evaluator

* fix: CEL v2 query engine

* chore: Add sample policy-v2

* chore: Remove deprecated API use

* fix: Remove deprecated API

* fix: Misc linter fixes

* fix: Linter fixes

* fix: Policy v2 sample

* refactor: Extract filter match rendering into common concern

* test: Update test case

* fix: JSON round trip problem by using PB messages for filter eval

* Improve DX by declaring enum constants in CEL env

* fix: Code generator for enum type names

* docs: Add policy dev enumgen docs

* chore: Add example policy

* test: Add test for CEL filter suite v2 analyser

* Code review fixes

* fix: Code review comments

* chore: Add CI check to ensure generated code is updated

* fix: Add nil guards during init
2025-10-02 09:01:50 +05:30
Kunal Singh
498f809e94
Merge pull request #605 from safedep/test/add-test-cases-for-relative-exclusion-matcher
test: Add test case for relative exclusion matcher
2025-10-01 17:10:04 +05:30
abhisek
c2cb4375f8
test: Add test case for relative exclusion matcher 2025-10-01 13:51:58 +05:30
Sahil Bansal
7f8b335393
update docs (#604) 2025-09-25 15:48:56 +05:30
Sahil Bansal
969404956c
skips analytics init for root or help cmd/flags (#603)
* skips analytics init for root or help cmd/flags

* fix analytics init only on non-help cmds
2025-09-24 19:23:54 +05:30
Sahil Bansal
e9d3da03db
Fix Attest build provenance failing (#602)
* upload dist folder to make it accessible in provenance job

* pin commit sha's for uploading & downloading artifacts
2025-09-22 15:29:21 +05:30
Abhisek Datta
ec792952f8
fix/dir reader log path failure (#599)
* fix: Avoid hard failure in dir scanner on path errors

* fix: Ensure dir reader fails if root path doesn't exist
2025-09-21 15:59:45 +00:00
Copilot
d94a05844e
Add custom reference URL and version format control for OSV malware reports (#598)
* Initial plan

* Implement OSV report improvements with custom reference URLs and version format control

- Add --report-reference-url flag for custom reference URLs instead of default platform.safedep.io
- Add --range flag to control version representation:
  - With --range: use range-based versioning (SEMVER/ECOSYSTEM)
  - Without --range: use explicit versions array (new default)
- Update OSV report generation to support both modes
- Add comprehensive tests for new functionality
- Backward compatibility maintained for existing functionality

Co-authored-by: KunalSin9h <82411321+KunalSin9h@users.noreply.github.com>

* fix: custom reference url and added docs

* fix: docs table layout

* fix: test

* refactor: remove unnecessary else statement

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: KunalSin9h <82411321+KunalSin9h@users.noreply.github.com>
Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-09-17 16:09:32 +05:30
Sahil Bansal
c449d94dad
pin building version to sha (#595) 2025-09-13 18:53:52 +05:30
Arunanshu Biswas
c0144e60e3
feat: update go version to latest (#589)
* feat: update go version to latest

* update workflow

* use bookworm

* revert fixture

* fix dockerfile run

* use more modern debian image

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-09-13 10:25:25 +05:30
Kunal Singh
d3c87b6e06
fix: scalibr issue when runningSystem is true (#591) 2025-09-08 16:56:56 +05:30
Arunanshu Biswas
0ae3560ba1
fix: mcp SSE hardening (#587) 2025-09-04 06:37:59 +05:30
Kunal Singh
e4e9dc2590
Merge pull request #586 from safedep/fix/npm-publish-use-head-branch-tag
use head_branch for extracting tag
2025-08-27 18:21:55 +05:30
Sahilb315
f2a4722d04 use head_branch for extracting tag 2025-08-27 18:03:04 +05:30
Sahil Bansal
850f2c1dc9
fix syntax issue (#585) 2025-08-27 16:06:29 +05:30
Sahil Bansal
6dcbd15923
fix npm publish workflow to execute after goreleaser completion (#581)
Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-08-27 08:06:00 +00:00
Kyle Kelly
82505f2460
Refactor goreleaser workflow to use attest-build-provenance (#584) 2025-08-27 07:16:50 +05:30
Kunal Singh
1afeb397f7
fix: extra space in ascii art (#582) 2025-08-26 09:10:45 +05:30
Sahil Bansal
5844d4ffd1
add support for generating sbom for homebrew installed packages (#571)
* add support for generating sbom for homebrew installed packages

* add brew test cases

* Update scan.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

* minor error improvements

* add brew ecosystem

* maintain consistency in ecosystem name

* rename `brew` flag to `homebrew`

---------

Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-25 12:00:02 +05:30
Kunal Singh
651b09b085
Merge pull request #579 from safedep/readme-gitlab-fix
Change vet CI Component path in README
2025-08-23 17:45:56 +05:30
Kunal Singh
118210c7c7
Merge branch 'main' into readme-gitlab-fix 2025-08-23 17:40:28 +05:30
Copilot
269b843bb7
Improve MCP vulnerability API performance by using dedicated endpoint (#574)
* Initial plan

* Update dependencies and plan Get Vulnerabilities Tool implementation

Co-authored-by: arunanshub <48434243+arunanshub@users.noreply.github.com>

* Add GetPackageVersionVulnerabilitiesOnly driver method and comprehensive tests

Co-authored-by: arunanshub <48434243+arunanshub@users.noreply.github.com>

* Complete implementation by registering new vulnerability tool in MCP server

Co-authored-by: arunanshub <48434243+arunanshub@users.noreply.github.com>

* Address feedback: Remove separate vulnerability tool and use dedicated API in existing method

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

* Fix scanner mock interface after protobuf dependency update

Co-authored-by: arunanshub <48434243+arunanshub@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: arunanshub <48434243+arunanshub@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-08-23 12:08:59 +00:00
Kunal Singh
68609f7397
Change vet CI Component path in README
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-08-23 17:37:01 +05:30
Kunal Singh
d0d21e6710
feat: updated vet in action demo gif (#578)
* feat: updated vet in action demo gif

* fix: replaced old gif

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-08-23 12:03:09 +00:00
Kunal Singh
319cfdac5e
Added screenshot image to top in readme (#577)
* Added screenshort image to top in readme

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>

* added local file

---------

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-08-23 17:27:58 +05:30
Kunal Singh
458391e6f0
fix: progress bar overlaping other previous tables etc (#576) 2025-08-22 17:35:08 +05:30
Kunal Singh
c8ad28bf1a
Merge pull request #572 from safedep/new-vet-banner
feat: new vet ascii banner
2025-08-21 22:10:44 +05:30
Kunal Singh
3791b9555c fix: check for commit lenght 2025-08-21 21:53:19 +05:30
Kunal Singh
30a7b484d1 feat: new vet ascii banner 2025-08-21 21:51:58 +05:30
Copilot
41684afa80
Fix OSV schema for PyPI ecosystem: use proper case "PyPI" and ECOSYSTEM range type (#570)
* Initial plan

* Fix OSV schema for PyPI ecosystem - use proper case and ECOSYSTEM range type

Co-authored-by: KunalSin9h <82411321+KunalSin9h@users.noreply.github.com>

* Add clarifying comments and rename ecosystem mapping variables for better intention revealing

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: KunalSin9h <82411321+KunalSin9h@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
2025-08-21 19:08:38 +05:30
Sahil Bansal
2d06114eb7
add cloud session refresh using refresh token functionality (#565)
* add cloud session refresh using refresh token functionality

* add ui msg & update globalConfig to fallback to default when nil

* rm unnecessary comment

* refactor access token checks and error handling for cloud session refresh

* print error to user for automatic re-login

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-08-19 06:26:24 +00:00
Sahil Bansal
52aa033fe4
add IsSuspicious value for reporting suspicious packages too (#567) 2025-08-18 17:56:24 +05:30
Kunal Singh
d8b83e2bc2
Merge pull request #566 from safedep/chore/misc-cleanup-20250815
chore: Misc cleanup and test improvements
2025-08-18 09:52:04 +05:30
Kunal Singh
b9ebcc71da
Merge branch 'main' into chore/misc-cleanup-20250815 2025-08-18 09:33:52 +05:30
Sahil Bansal
0f4c01b83a
add html reporter & create template for report (#559)
* add html reporter & create template for report

* updated table colors

* chore: rm unused code block

* add policy violations

* chore: rm extra var

* Update pkg/reporter/templates/report.templ

Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

* chore: rm extra file

* chore: rm unsued css property

* add html reporter & create template for report

* updated table colors

* chore: rm unused code block

* add policy violations

* chore: rm extra var

* Update pkg/reporter/templates/report.templ

Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

* chore: rm extra file

* chore: rm unsued css property

* return error when failing to create html reporter

---------

Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>
Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-08-18 09:33:18 +05:30
abhisek
7cb923b2fd
fix: safely handle global config in test runner 2025-08-15 21:28:23 +05:30
abhisek
e32784a09e
fix: Test to use t.Setenv instead of os 2025-08-15 20:36:20 +05:30
abhisek
db6832e782
chore: Misc cleanup and test improvements 2025-08-15 20:26:55 +05:30
Kunal Singh
4b80c4a624
Fix: truffle hog, invalid commit hash. (#564)
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-08-13 08:49:43 +00:00
Sahil Bansal
12785f9c05
add support for publishing vet to npm (#563)
* add support for publishing vet to npm

* Update .github/workflows/publish-npm.yml

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

* update npm package readme

---------

Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-08-12 22:02:33 +05:30
Sahil Bansal
7d4569fb3d
use tag version instead of commit hash (#557) 2025-08-11 12:14:32 +00:00
Teja Kummarikuntla
47939fafaf
fix(report): Add commas between tags in generated markdown (#553)
* Seperate Tags with Comma in Report

* Delete pkg/.DS_Store

Signed-off-by: Teja Kummarikuntla <34749692+tejakummarikuntla@users.noreply.github.com>

* Update pkg/reporter/markdown.go

Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
Signed-off-by: Teja Kummarikuntla <34749692+tejakummarikuntla@users.noreply.github.com>

---------

Signed-off-by: Teja Kummarikuntla <34749692+tejakummarikuntla@users.noreply.github.com>
Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-07-31 21:23:10 +05:30
Sahil Bansal
e68ead129b
add support for extensions purl (#551)
* add support for extensions purl

* Update pkg/common/purl/purl_test.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

---------

Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-30 08:15:19 +05:30
Rohan Mishra
742365bc18
fix(tools): prevent nil pointer panic in GetPackageLicenseInfo handler (#548)
Signed-off-by: Rohan <315scisyb2020rohanmishra@gmail.com>
2025-07-27 18:51:59 +05:30
Kunal Singh
dee54e5184
Merge pull request #546 from safedep/deepwiki
added ask deepwiki badge.
2025-07-24 10:09:58 +05:30
Kunal Singh
1e84769891
added ask deepwiki badge.
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-07-23 21:42:10 +05:30
Kunal Singh
16a67216b4
Merge pull request #484 from safedep/fix/policy-violation-suspicious-#483
Fix/policy violation on  suspicious packages without paranoid mode #483
2025-07-22 10:27:18 +05:30
Abhisek Datta
0b4e76d858
Merge branch 'main' into fix/policy-violation-suspicious-#483 2025-07-22 10:11:36 +05:30
Abhisek Datta
ccd2c48e0c
fix: Misc cleanup of exclusion matcher initialization (#545) 2025-07-22 08:55:34 +05:30
Sahil Bansal
150cad94a6
Support exclusion patterns for lockfiles flag (#543)
* introduce config for lockfile reader

* add exclusion support

* add test cases for exclusion patterns

* refactor: introduce common exclusion matcher and update lockfile reader to use it

* chore: rm print statements

* refactor: use better naming for tests

* use doublestar lib for supporting dir reader exclusion patterns

* fix: path handling in exclusion matcher to support relative & absolute paths
2025-07-22 08:37:41 +05:30
Kunal Singh
c488d980cc fix: fail fast only on malware 2025-07-21 13:45:22 +05:30
Kunal Singh
3d8b7c5b63 feat: warning in markdown summary report for suspicious packages 2025-07-21 13:16:19 +05:30
Abhisek Datta
b4976630da
Merge branch 'main' into fix/policy-violation-suspicious-#483 2025-07-21 09:14:36 +05:30
Sahil Bansal
3d6d8ed036
Add github actions sync resolver (#539)
* feat: add GHA env resolver

* refactor: expose sync reporter resolver constructors

* fix: use os.LookupEnv for better GHA detection

* fix typo

* use environment sync resolver

* test: add test cases & fix naming

* Update pkg/reporter/sync_test.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>

* modify sync resolver tests

* fix tests failing in ci/cd

---------

Signed-off-by: Sahil Bansal <bansalsahil315@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-07-21 09:11:24 +05:30
Sahil Bansal
075627f53f
Add test cases for editor based extensions scanning (#542)
* fail fast if distribution is not among our supported editors

* tests: add test cases for each supported editor

* rm unused extensions
2025-07-19 00:17:47 +05:30
Abhisek Datta
1e2b75fa9c
Merge branch 'main' into fix/policy-violation-suspicious-#483 2025-07-17 09:29:18 +05:30
Sahil Bansal
06988f9b33
OpenVSX extensions scanning support (#536)
* feat(readers): Add OpenVSX ecosystem support

* refactor: use better naming conventions

* refactor: improve extensions reader with structured config
2025-07-15 18:40:02 +05:30
Abhisek Datta
c3d96dbef5
fix: Improve Agentic Query Prompt and Tools (#538) 2025-07-14 22:46:37 +05:30
Abhisek Datta
5f4cccbc85
feat: Add Support for Agentic Query and Analysis (#535)
* Add initial UI for agent mode

* fix: Cleanup and define agent contract

* Add react agent

* Add interactions memory

* Add support for stdio based MCP integration

* Add basic sqlite3 report generator

* fix: Persist vulnerabilities with package relation

* fix: Persist license information

* refactor: Agents into its own command package

* feat: Add support for tool calling introspection

* refactor: UI to hide implementation detail

* sqlite3 reporter persist dependency graph

* fix: Support multiple LLM provider for agent

* docs: Update agents doc

* docs: Remove deprecated query docs

* fix: UI tests

* fix: Linter issue

* Add support for prompt mode

* Improve UI with animation

* Fix UI tests after update

* Add OpenSSF scorecard persistence

* Add slsa provenances in sqlite3 reporter

* Add test cases for sqlite3 reporter

* Fix agent doc

* fix: Sqlite3 reporter use safe accessors

* feat: Add support for fast model

* feat: Simplify and streamline agent UI for better user experience

- Remove decorative borders and excessive styling to maximize output area
- Implement clean minimal design similar to modern TUI interfaces
- Add bordered input area for clear visual separation
- Move thinking indicator above input area for better visibility
- Enhance input field reset logic for proper line alignment
- Remove verbose help text and status messages
- Optimize layout calculations for full width utilization
- Add smooth animations for agent thinking state with spinner
- Clean up code structure and remove unused progress bar functionality

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: Improve agent status line

* test: Update UI tests

* fix: Use terminal safe rendering

* fix: Fix nil deref without storing empty strings in DB

* fix: Support overwriting sqlite3 database

* fix: Data model to use m2m between manifest and package

* style: Fix linter issue with unused variables

* Misc fixes

* Add test for agent memory

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-11 18:37:44 +05:30
Copilot
cd7caffb4a
Add HTTP HEAD request support to SSE MCP server (#533)
* Initial plan

* Add HTTP HEAD request support to SSE MCP server

- Created sseHandlerWithHeadSupport wrapper to handle HEAD requests to /sse endpoint
- HEAD requests return same headers as GET (text/event-stream, no-cache, etc.) without body
- Modified NewMcpServerWithSseTransport to use the wrapper
- Added comprehensive unit and integration tests
- Updated documentation to mention HEAD support for SSE endpoint
- Enables tools like Langchain to probe endpoint for health/capability checks

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

* Add HTTP HEAD request support to SSE MCP server

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

* Fix linter issues: remove trailing whitespace and handle w.Write error

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
2025-07-05 13:41:37 +00:00
Copilot
548ede77b8
Fix OSV report generation fallback value for 'introduced' version from "0.0.0" to "0" (#532)
* Initial plan

* Fix OSV introduced version fallback from 0.0.0 to 0 per OSV schema

Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: abhisek <31844+abhisek@users.noreply.github.com>
2025-07-04 11:47:10 +05:30
Kunal Singh
3fa7307d93
Merge pull request #529 from safedep/chore/sync-reporter-linter-fixes-cleanup
chore: Sync reporter linter fixes
2025-06-30 21:55:53 +05:30
abhisek
5cc80f9f88
chore: Sync reporter linter fixes 2025-06-30 21:46:50 +05:30
Omkar Phansopkar
387f6aeb72
Updated instructions for mcp server setup (#527)
* Updated instructions for mcp server setup

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Updated vscode usage image

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Spell vscode full form

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Added sse instructions

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

---------

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-28 18:13:48 +05:30
Omkar Phansopkar
200257bab3
Merge pull request #517 from safedep/chore/updateDeps
Updated deps and minor refactoring
2025-06-24 15:21:47 +05:30
Omkar Phansopkar
a87e6ab466
Updated deps
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-24 14:46:14 +05:30
Omkar Phansopkar
a0f6467e85
Merge branch 'main' into chore/updateDeps 2025-06-24 14:43:32 +05:30
Abhisek Datta
78e2bad49b
feat: Malicious Packages (OSV) Reporter for Inspect Command (#518)
* Add osv reporter

* fix: Pass config to openssf report generator

* fix: file name and check if already osv record exists' (#519)

---------

Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-06-24 09:12:34 +00:00
Omkar Phansopkar
4f989c59f6
Fix e2e: scenario-11-code-csvreport.sh (#522)
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-24 14:39:02 +05:30
Omkar Phansopkar
932269d6bb
Updated contributing.md
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-19 20:22:04 +05:30
Omkar Phansopkar
7a2a365136
Updated testcase
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-14 15:44:29 +05:30
Omkar Phansopkar
459a246488
Updated docker go version
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-14 15:26:53 +05:30
Omkar Phansopkar
966971b941
Updated go version in CI workflows
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-14 15:16:33 +05:30
Omkar Phansopkar
f9d17487ad
Updated deps and minor refactoring
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-06-14 15:09:11 +05:30
Kunal Singh
8b71c540e6
feat: added cargo.lock scalibr parser (#512)
* feat: added cargo.lock scalibr parser

* fix: invalid manifest ref in cargo

* fix: list parser test - increment to 22

* fix: added cargo in supported ecosystems
2025-06-06 16:43:40 +05:30
Abhisek Datta
cccf646856
chore: Add multi-arch build for docker container (#510)
* chore: Add multi-arch build for docker container

* fix: Multi-platform build verification

* fix: Multi-platform build verification

* fix: MCP server docs

* chore: Add to cursor button for vet MCP Server
2025-06-06 12:59:05 +05:30
Kunal Singh
124199b331
docs(readme): added pkg.go.dev badge. (#509)
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-06-05 08:51:32 +00:00
Abhisek Datta
5a5a9518c6
feat: Add Support for vet MCP Server (#502)
* fix: MCP server with update mcp-go

* docs: Update MCP usage docs

* docs: Update MCP usage docs

* chore: Update DRY for Go adapter

* test: Add mcp driver test cases

* test: Simplify test cases

* docs: Update README

* docs: Update README

* test: Add test case for mcp tool

* test: Refactor for common concerns

* test: Add tool tests

* docs: Update MCP server docs

---------

Co-authored-by: Kunal Singh <kunalsin9h@gmail.com>
2025-06-05 11:00:43 +05:30
Sahil Bansal
3d94f0f710
Fixes duplicate & incorrect version in requirements.txt & empty Upgrade To Version Suggestion (#401)
* fixes #344

* fixed duplicate & incorrect version for requirements.txt

* fix return err if lfParser.Parse fails

* fix: Update edge cases and add test

---------

Co-authored-by: abhisek <abhisek.datta@gmail.com>
2025-06-04 09:44:08 +05:30
Kunal Singh
4f43177976
fix: pomxml parser not working when renamed files (#505)
* fix: pomxml parser not working when renamed files

* fix: pom.xml parsing with differnet filename

* removed test file'

* remvoed unused code
2025-06-03 13:49:32 +05:30
Kunal Singh
0a2d642ea8
Docs: added instructions for container image scanning & and fix misc (#501)
* fix: scan flgas, report-cdx and report-graph

* added more instructions for container image scanning
2025-05-30 17:40:47 +05:30
Kunal Singh
49cc6ca395
Support for local docker and tar images in container scanning. (#497)
* refactor: convert current image resolution into workflow pattern

* feat: image from local tarball folder

* feat: image from local docker catalog

* refacot: decompose docker image catalog resolver into multiple functions

* refactor: using utilit function for logging and return error

* feat: remove tem tar dir after image obj is created

* refactor: handle empty nil error in log and error funciton

* removed local image not supported test

* fix: error fmt.Errorf with non-constant values

* go mod tidy

* fix: linter unreachable  code

* refactor: removed unwanted parameter

* test: added scenerio for different image scan operations

* fix: added scenario into all.sh

* fix: missed .sh extension for one entry

* fix: test bad file path for local tar scan

* remvoed logger and error combined function

* refactor: using context form top of tree

* feat: using custom error for image resolution unsupported

* refactor: returning unsupported workflow error for each docker api fail

* feat: added no-remote flag for disable remote fetch

* feat: --image-no-remote

* fix: test, creating temp files witn \/ causing issue

* chore: Misc cleanup for Container Image Resolver (#499)

* chore: Misc cleanup

* fix: Bug with docker image resolver

* fix: Error msg

* chore: Improve debug logging for docker enumeration

* chore: Improve debug logging for docker enumeration

---------

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-05-29 22:36:49 +05:30
Abhisek Datta
a2c003f634
docs: Update README (#496) 2025-05-29 00:03:48 +05:30
Abhisek Datta
72e08bdd8a
refactor: Sync reporter to allow env resolver adapter (#495)
* refactor: Sync reporter to allow env resolver adapter

* fix: Set optional params only when not empty

* fix: linter warning
2025-05-27 22:00:50 +05:30
Kunal Singh
1f8a5750d2
feat: container scanning (#489)
* feat: container scanning

* fix: tests

* refactor: added commens and set running-system for remote image to false

* using standalone extractors with all scope

* feat: handle manifects

* using set for duplicate purl

* feat: added initial tests

* refactor: creating manifest from local and modified tests

* refactor: decouple parser and reader for container scanning

* refactor: seperated image and reader config

* refactor: using applicatoin name to purl

* refactor: removed technical osv-scalibr names from error message

* refactor: misc

* added analytics

* moved container image reader test to e2e test

* refactor: getting image in consutrctor

* refactor: composit grouping of ecosystem and file

* feat: cache to reudce duplicate packages

* refactor: removed json-dump-dir output dir

* feat: added ui for better UX

* test: skip when not e2e

* refactor: made scalibr image object reference private

* test: application name testing'

* test, different image with invalid cases

* feat: clean up image after use

* refactor: fetching image in enum manifests

* fix: tests, handing error from enum manifests

* tests: added test for local image not supported

* refactor: removed ui reference in container reader
2025-05-27 20:45:37 +05:30
Kunal Singh
826b8eafdf
Fix/ Bug in Resolving Package Version in Maven POM with Dependency Management (#487)
* feat: pom.xml dependency resolver

* feat: manifest from packages

* feat: disable osv-scalibr's native loggin

* fix: parser test, update total parsers count'

* refactor: using manifest's NewPackageManifestFromLocal and AddPackage methods

* fix: tests, package enumertaion with new pom.xml parser

* fix: docker image with go 1.24.2

* feat(test): pom parser

* refactor: extracted commaon osv-scalibr's function in scalibr.go

* refactor: setting scalibr logger in init function
2025-05-20 18:10:49 +05:30
Omkar Phansopkar
5c7ab43567
Merge pull request #482 from safedep/fix/481-sarif-report-builder
fix: SARIF report builder to handle vuln and malicious code rule index
2025-05-14 12:32:43 +05:30
Kunal Singh
a04cf78657 refactor: simplified 2025-05-09 16:19:41 +05:30
Kunal Singh
9e9abdd162 fix: tests, common pkgManifest causing issues due to multiple packages 2025-05-09 15:58:27 +05:30
Kunal Singh
5840ebd227 test: check if policy is violated 2025-05-09 11:47:37 +05:30
Kunal Singh
f2a2eb0548 fix: unwanted policy violation emmition for suspicious packages 2025-05-08 20:45:55 +05:30
abhisek
ac1c83393f
fix: SARIF report builder to handle vuln and malicious code rule index 2025-05-05 17:55:23 +05:30
Abhisek Datta
a77be8f4c4
feat: Add manifest source in csv report (#480) 2025-04-28 23:11:55 +05:30
infosecwonderland
eebae09e82
feat: add excludeRepos support to GithubOrgReader (#476)
* feat: add excludeRepos support to GithubOrgReader

* feat: add excludeRepos support to GithubOrgReader

* Syntax changes

* fix: excluded repo variable declartion

* fix: scan command to include excluded repo config

---------

Co-authored-by: abhisek <abhisek.datta@gmail.com>
2025-04-28 15:03:54 +05:30
Omkar Phansopkar
e90756d5a3
CDX reporting in readme (#479)
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-28 12:00:47 +05:30
Abhisek Datta
c795255e35
docs: Update vet logo (#475)
* docs: Update vet logo

* fix: logo size

* docs: Improve README by using collapsible sections

* docs: Add interactive tutorial

* docs: Update vet logo

* docs: Update README

* docs: Update README

* docs: Update vet logo

* docs: Update README

* fix: Revert star history URL

* fix: README image
2025-04-24 23:56:02 +05:30
Abhisek Datta
36d5c021f3
fix: Handle github reader reading directory (#477) 2025-04-24 22:24:24 +05:30
Abhisek Datta
3490812ed1
chore: Add anonymous telemetry collector (#468)
* chore: Add anonymous telemetry collector

* fix: Posthog property handling
2025-04-22 15:53:32 +05:30
Omkar Phansopkar
5b766bb27b
Merge pull request #465 from safedep/feat/add-query-malysis-enricher
feat/add query malysis enricher
2025-04-21 11:16:40 +05:30
abhisek
0bdbf2da8a
test: Add test case for malware query enricher 2025-04-20 13:30:56 +05:30
abhisek
00eb5c8ec7
feat: Update markdown summary reporter for malware query 2025-04-20 10:45:59 +05:30
abhisek
0a3fc8d428
chore: Update dependencies 2025-04-19 22:15:51 +05:30
abhisek
3d7ea62f61
feat: Add malware query enricher 2025-04-19 22:11:17 +05:30
abhisek
88f5178a05
feat: Add community service API endpoint 2025-04-19 20:49:52 +05:30
Kunal Singh
3d9639d0ef
feat: github repos version resolution (#458)
* feat: github repos version resolution

* fix: malware analysis e2e testing

* fix: e2e testing for malware analysis using vet scan

* revert: e2e testing

* fix(test): remove bad e2e tests commands, scan without version has not effect

* fix: test failing 🔥, for scoped packages

* feat(e2e): added inspect malware command

* fix: use of internal code to library

* refactor: Maintain separation of concerns and loose coupling

* fix: PURL reader test

---------

Co-authored-by: abhisek <abhisek.datta@gmail.com>
2025-04-12 08:05:01 +05:30
Nilanjan De
03e1a10c1d
chore: correct typos (#460) 2025-04-11 21:19:02 +00:00
Abhisek Datta
7f88f83a8c
ci: Fix codecov upload step (#457) 2025-04-10 16:23:19 +05:30
Kunal Singh
0d1ba75d4c
feat(inspect): resolve version of npm, pypi, rubygem packages' (#451)
* feat(inspect): resolve version of npm, pypi, rubygem packages'

* chore: go mod tidy

* feat: added version resolve to purl reader and added tests

* feat(inspect): resolve version of npm, pypi, rubygem packages'

* fix: updated safedep/dry version

* fix: removed unused block of code, unremoved after refactoring

* refactor: remove custom registry adapter function with predefined

* fix: error handing

* refactor: print statement for better aligning with current code

* refactor: added helpful error message

* Update cmd/inspect/malware.go

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>

* Update pkg/common/packageregistry.go

Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>

* feat(e2e test): malware analysis without version

---------

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
Co-authored-by: Abhisek Datta <abhisek.datta@gmail.com>
2025-04-09 14:39:30 +05:30
Abhisek Datta
2e0c4a5d3d
ci: Add codecov reporting (#454) 2025-04-09 11:46:22 +05:30
Omkar Phansopkar
923fc4744c
Implemented CycloneDX reporter with metadata, packages & vulnerabilities (#434)
* Implemented CycloneDX reporter with metadata, packages & vulnerabilities

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Refactor to using PtrTo instead of dereferencing

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Minor lint fixes

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Implemented CycloneDX features - Licenses, Vulnerability & annotations

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Support malware in cyclonedx bom

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Script for SPDX licenses, prevent duplicate vulnerabilities

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Fix comment typo

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Test cases for reader application names

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Replaced StringPtr with PtrTo

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

* Tests for cyclonedx reporter and cvss score calculation

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>

---------

Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-04-08 19:54:50 +05:30
Omkar Phansopkar
859ce29ab0
Fixed incorrect dependencies provided by Package.GetDependencies (#450)
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-07 13:44:08 +05:30
Kunal Singh
0ad855f2a8
Feat/gitlab policy violations (#445)
* feat: added policy violation support in gitlab reporting

* feat(gitab): policy violations entries in report

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>

* fix(gitlab): identifier id

* fix: using info severity level for policy violations

---------

Signed-off-by: Kunal Singh <kunalsin9h@gmail.com>
2025-04-07 12:00:40 +05:30
Arunanshu Biswas
f6797d0d6f
feat(reporter): sync malware analysis report (#444)
* build(deps): update dependencies

* feat(reporter): sync malware analysis report

* refactor: fix verification record

* test(reporter/sync): add basic tests for sync
2025-04-03 20:23:30 +05:30
Kunal Singh
6cf88c2e86
Merge pull request #441 from safedep/feat/#430-sarif-vuln-malware
Added vulnerabilities & malware in SARIF reports
2025-04-02 10:50:58 +05:30
Omkar Phansopkar
aaa1794e89
Removed unnecessary debug log
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-02 10:38:23 +05:30
Omkar Phansopkar
0bfd37027f
Fix incorrect summary for Malware analyzer event filters
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-02 10:32:40 +05:30
Omkar Phansopkar
d7f7a6c72e
Use common ToolMetadata for all reporters and default-enable vuln & malware in SARIF
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-01 21:10:45 +05:30
Omkar Phansopkar
976c5317ac
Fix uninitialised vulncache
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-01 19:58:59 +05:30
Omkar Phansopkar
86382bbc70
Refactor tool meta data config & using separate vulncache
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-04-01 19:52:08 +05:30
Omkar Phansopkar
d0111cec20 Added vulnerabilities & malware in SARIF reports
Signed-off-by: Omkar Phansopkar <omkarphansopkar@gmail.com>
2025-03-31 20:59:29 +05:30
417 changed files with 80700 additions and 2459 deletions

View File

@ -8,6 +8,17 @@
"-i",
"ghcr.io/safedep/pinner-mcp:latest"
]
},
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"server",
"mcp"
]
}
}
}
}

View File

@ -0,0 +1,10 @@
---
description:
globs:
alwaysApply: true
---
Always use vet-mcp to vet any open source library package suggested by AI generated code before installation.
Follow the rules below to use vet-mcp:
- Try to find the latest version. If not found, it is likely a slopsquatting vulnerability
- Always check for critical vulnerabilities and malware

View File

@ -11,6 +11,35 @@ permissions:
contents: read
jobs:
check-generated-code:
timeout-minutes: 10
runs-on: ubuntu-latest
steps:
- name: Checkout Source
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up Go
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
with:
go-version-file: go.mod
- name: Run code generation
run: make generate
- name: Check for uncommitted changes
run: |
if [[ -n $(git status --porcelain) ]]; then
echo "ERROR: Generated code is out of sync!"
echo "Please run 'make generate' and commit the changes."
echo ""
echo "Files with changes:"
git status --porcelain
echo ""
echo "Diff:"
git diff
exit 1
fi
run-test:
timeout-minutes: 15
runs-on: ubuntu-latest
@ -21,14 +50,13 @@ jobs:
- name: Set up Go
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
with:
go-version: 1.24
check-latest: true
go-version-file: go.mod
- name: Build and Test
run: |
go mod tidy
go build
go test -v ./...
go test -coverprofile=coverage.txt -v ./...
env:
VET_E2E: true
@ -36,6 +64,12 @@ jobs:
# test suites that use GitHub API
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Upload Coverage
if: (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) || github.event_name == 'push'
uses: codecov/codecov-action@0565863a31f2c772f9f0395002a31e3f06189574 # v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
run-e2e:
timeout-minutes: 30
runs-on: ubuntu-latest
@ -46,7 +80,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
with:
go-version: 1.24
go-version-file: go.mod
check-latest: true
- name: Build vet
@ -75,26 +109,30 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout Source
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Checkout Source
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
- name: Setup QEMU
uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@b5ca514318bd6ebac0fb2aedd5d36ec1b5c232a2 # v3
- name: Build Container Image
run: |
docker buildx build --platform linux/amd64 --load \
-t build-container-test:latest .
- name: Build Multi-Platform Container Image (verification only)
run: |
docker buildx build --platform linux/amd64,linux/arm64 \
-t build-container-test:latest .
- name: Test Container Image
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
docker run --rm \
-e VET_API_KEY=${{ secrets.SAFEDEP_CLOUD_API_KEY }} \
-e VET_CONTROL_TOWER_TENANT_ID=${{ secrets.SAFEDEP_CLOUD_TENANT_DOMAIN }} \
build-container-test:latest \
auth verify
- name: Build and Load Native Platform Image for Testing
run: |
docker buildx build --platform linux/amd64 --load \
-t build-container-test:latest .
- name: Test Container Image
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository
run: |
docker run --rm \
-e VET_API_KEY=${{ secrets.SAFEDEP_CLOUD_API_KEY }} \
-e VET_CONTROL_TOWER_TENANT_ID=${{ secrets.SAFEDEP_CLOUD_TENANT_DOMAIN }} \
build-container-test:latest \
auth verify

View File

@ -13,10 +13,10 @@ name: "CodeQL"
on:
push:
branches: [ "main" ]
branches: ["main"]
pull_request:
# The branches below must be a subset of the branches above
branches: [ "main" ]
branches: ["main"]
permissions:
contents: read
@ -35,34 +35,34 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'go' ]
language: ["go"]
steps:
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Checkout repository
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- name: Set up Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: 1.24
check-latest: true
- name: Set up Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version-file: go.mod
check-latest: true
- name: Initialize CodeQL
uses: github/codeql-action/init@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
- name: Initialize CodeQL
uses: github/codeql-action/init@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
- run: |
go mod tidy
go build
- run: |
go mod tidy
go build
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
category: "/language:${{matrix.language}}"
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@b8d3b6e8af63cde30bdc382c0bc28114f4346c88 # v2
with:
category: "/language:${{matrix.language}}"

View File

@ -27,45 +27,130 @@ jobs:
id-token: write
steps:
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
with:
submodules: true
fetch-depth: 0
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
with:
submodules: true
fetch-depth: 0
- name: Registry Login
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Registry Login
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Setup QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7
- name: Setup QEMU
uses: docker/setup-qemu-action@2b82ce82d56a2a04d2637cd93a637ae1b359c0a7
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55
- name: Setup Docker Buildx
uses: docker/setup-buildx-action@885d1462b80bc1c1c7f0b00334ad271f09369c55
- name: Build and Push Container Image
run: |
# Get the tag if this was a tag push event
if [[ "${{ github.ref_type }}" == "tag" ]]; then
TAG=${{ github.ref_name }}
# Validate tag format (must be vX.Y.Z)
if [[ $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# Build and push with both version tag and latest
- name: Build and Push Container Image
run: |
# Get the tag if this was a tag push event
if [[ "${{ github.ref_type }}" == "tag" ]]; then
TAG=${{ github.ref_name }}
# Validate tag format (must be vX.Y.Z)
if [[ $TAG =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
# Build and push with both version tag and latest
docker buildx build --push --platform linux/amd64,linux/arm64 \
-t $REGISTRY/$IMAGE_NAME:$TAG \
-t $REGISTRY/$IMAGE_NAME:latest \
.
else
echo "Invalid tag format. Must be in format vX.Y.Z (e.g. v1.2.3)"
exit 1
fi
else
# For non-tag pushes, just use latest tag
docker buildx build --push --platform linux/amd64,linux/arm64 \
-t $REGISTRY/$IMAGE_NAME:$TAG \
-t $REGISTRY/$IMAGE_NAME:latest \
.
else
echo "Invalid tag format. Must be in format vX.Y.Z (e.g. v1.2.3)"
fi
publish-mcp-registry:
if: startsWith(github.ref, 'refs/tags/') # only run this when new tag is publish
needs: build
runs-on: ubuntu-latest
permissions:
id-token: write # Required for OIDC authentication
contents: read
defaults:
run:
working-directory: ./.mcp-publisher
steps:
- name: Checkout code
uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6
- name: Ensure jq is installed
run: sudo apt-get update && sudo apt-get install -y jq
- name: Get version from tag
# Strip 'v' prefix from tag (e.g., v1.0.0 -> 1.0.0) as
# - we want clean version (x.y.z) without v prefix, since its already added by registry UI
# - in case of docker image, we hardcode in server.json docker image identifier
run: echo "VET_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: fill version in server.json
run: sed -i "s/VERSION_FROM_ENV/$VET_VERSION/g" server.json
# publish mcp server
- name: Install mcp-publisher
run: |
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
- name: Authenticate to MCP Registry
run: ./mcp-publisher login github-oidc
- name: Publish server to MCP Registry
run: ./mcp-publisher publish
verify-publish-mcp-registry:
needs: publish-mcp-registry
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Ensure jq is installed
run: sudo apt-get update && sudo apt-get install -y jq
- name: Get version from tag
# Strip 'v' prefix from tag (e.g., v1.0.0 -> 1.0.0) as
# - we want clean version (x.y.z) without v prefix, since its already added by registry UI
# - in case of docker image, we hardcode in server.json docker image identifier
run: echo "VET_VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_ENV
- name: Query MCP Registry and verify server is published
env:
SERVER_NAME: "io.github.safedep/vet-mcp"
REGISTRY_URL: "https://registry.modelcontextprotocol.io/v0.1/servers"
run: |
export EXPECTED_VERSION=$VET_VERSION
echo "Checking MCP Registry for $SERVER_NAME"
# Query registry
url="${REGISTRY_URL}?search=${SERVER_NAME}"
echo "Requesting: $url"
http_status=$(curl -s -o response.json -w "%{http_code}" "$url")
if [ "$http_status" -ne 200 ]; then
echo "Registry query failed with HTTP status $http_status"
cat response.json || true
exit 1
fi
else
# For non-tag pushes, just use latest tag
docker buildx build --push --platform linux/amd64,linux/arm64 \
-t $REGISTRY/$IMAGE_NAME:latest \
.
fi
# Pretty print the response for debugging
echo "Registry response (truncated):"
jq 'if .servers then {servers: (.servers | length)} else . end' response.json
# Check for name and version match
jq -e --arg name "$SERVER_NAME" --arg ver "$EXPECTED_VERSION" 'any(.servers[]; .server.name == $name and .server.version == $ver)' response.json >/dev/null || {
echo "ERROR: Server $SERVER_NAME with version $EXPECTED_VERSION not found"
echo "Full response:"
cat response.json
exit 1
}
echo "Found server $SERVER_NAME with version $EXPECTED_VERSION"

View File

@ -4,7 +4,7 @@
#
# Source repository: https://github.com/actions/dependency-review-action
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
name: 'Dependency Review'
name: "Dependency Review"
on: [pull_request]
permissions:
@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: 'Checkout Repository'
- name: "Checkout Repository"
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
- name: 'Dependency Review'
- name: "Dependency Review"
uses: actions/dependency-review-action@cc4f6536e38d1126c5e3b0683d469a14f23bfea4 # v3

65
.github/workflows/gh-pages-deploy.yml vendored Normal file
View File

@ -0,0 +1,65 @@
name: CLI Reference Manual GitHub Pages Deploy
on:
push:
branches:
- main
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "pages"
cancel-in-progress: false
env:
SOURCE_GEN_DIR: ./docs/manual
jobs:
# Build Jekkll (md -> html)
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@0aaccfd150d50ccaeb58ebd88d36e91967a5f35b # v5
with:
go-version-file: go.mod
- name: Build vet
run: go build
- name: Generate MD Docs in ${{ env.SOURCE_GEN_DIR }}
run:
./vet doc generate --markdown ${{ env.SOURCE_GEN_DIR }}
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ${{ env.SOURCE_GEN_DIR }}
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
# Deployment job
deploy:
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4

View File

@ -6,23 +6,22 @@ on:
permissions:
contents: read
pull-requests: read
jobs:
golangci:
name: lint
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version: 1.24
cache: false
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
go-version-file: go.mod
- name: golangci-lint
uses: golangci/golangci-lint-action@3a919529898de77ec3da873e3063ca4b10e7f5cc
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8
with:
version: latest
args: --issues-exit-code=1 --timeout=10m
only-new-issues: true
skip-pkg-cache: true
skip-build-cache: true

View File

@ -3,7 +3,7 @@ name: Release Automation
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
- "v[0-9]+.[0-9]+.[0-9]+"
concurrency: ci-release-automation
@ -20,7 +20,7 @@ jobs:
outputs:
hashes: ${{ steps.hash.outputs.hashes }}
permissions:
contents: write # for goreleaser/goreleaser-action to create a GitHub release
contents: write # for goreleaser/goreleaser-action to create a GitHub release
packages: write # for goreleaser/goreleaser-action to publish docker images
runs-on: ubuntu-latest
env:
@ -36,7 +36,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34
with:
go-version: 1.24
go-version-file: go.mod
check-latest: true
- name: ghcr-login
uses: docker/login-action@dd4fa0671be5250ee6f50aedf4cb05514abda2c7 # v1
@ -75,27 +75,31 @@ jobs:
uses: goreleaser/goreleaser-action@286f3b13b1b49da4ac219696163fb8c1c93e1200 # v6.0.0
with:
distribution: goreleaser
version: '~> v2'
version: "~> v2"
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
- name: Upload dist folder
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: dist-artifacts
path: dist/
- name: Generate subject
id: hash
env:
ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}"
run: |
set -euo pipefail
checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path')
echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT"
provenance:
needs: [goreleaser]
permissions:
actions: read # To read the workflow path.
id-token: write # To sign the provenance.
contents: write # To add assets to a release.
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0
with:
base64-subjects: "${{ needs.goreleaser.outputs.hashes }}"
upload-assets: true
private-repository: false
attestations: write # To write attestations
runs-on: ubuntu-latest
steps:
- name: Download dist folder
uses: actions/download-artifact@634f93cb2916e3fdff6788551b99b062d0335ce0 # v5.0.0
with:
name: dist-artifacts
path: dist/
- name: Attest build provenance (checksums)
uses: actions/attest-build-provenance@e8998f949152b193b063cb0ec769d69d929409be # v2.4.0
with:
subject-checksums: dist/checksums.txt

63
.github/workflows/publish-npm.yml vendored Normal file
View File

@ -0,0 +1,63 @@
name: Publish NPM Package
on:
workflow_run:
workflows: ["Release Automation"]
types:
- completed
jobs:
publish-npm:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
permissions:
contents: read
id-token: write
outputs:
package_version: ${{ steps.version.outputs.version }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "18"
registry-url: "https://registry.npmjs.org"
- name: Extract Tag Version
id: version
run: |
TAG_VERSION="${{ github.event.workflow_run.head_branch }}"
if [[ "$TAG_VERSION" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
VERSION="${TAG_VERSION#v}" # Remove leading 'v'
echo "version=$VERSION" >> $GITHUB_OUTPUT
else
echo "No valid tag found in head_branch: $TAG_VERSION"
exit 1
fi
- name: Prepare package
run: |
cd publish/npm
npm version ${{ steps.version.outputs.version }} --no-git-tag-version
- name: Publish to npm
run: |
cd publish/npm
npm publish --provenance
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
test-installation:
needs: publish-npm
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node-version: ["14", "18", "20"]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Test installation
run: |
npm install -g @safedep/vet@${{ needs.publish-npm.outputs.package_version }}
vet version
vet --help || true

View File

@ -10,9 +10,9 @@ on:
# To guarantee Maintained check is occasionally updated. See
# https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
schedule:
- cron: '35 22 * * 0'
- cron: "35 22 * * 0"
push:
branches: [ "main" ]
branches: ["main"]
# Declare default permissions as read only.
permissions: read-all

View File

@ -20,6 +20,6 @@ jobs:
uses: trufflesecurity/trufflehog@8b6f55b592e46ac44a42dc3e3dee0ebcc0f56df5
with:
path: ./
base: main
head: HEAD
base: ${{ github.event.pull_request.base.sha }}
head: ${{ github.event.pull_request.head.sha }}

View File

@ -0,0 +1,36 @@
name: Container Scan E2E
on:
push:
branches: [ main ]
pull_request:
permissions: read-all
jobs:
e2e-scan:
name: E2E Scan on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout Source
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5
- name: Set up Go
uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6
with:
go-version-file: go.mod
- name: Build and Test
run: |
make
- name: Run container scan tests
shell: bash
run: |
./vet scan --image alpine:latest
./vet scan --image ghcr.io/safedep/vet:latest
./vet scan --image node:20

6
.gitignore vendored
View File

@ -23,3 +23,9 @@
dist/
/.env.dev
.vscode/
# MacOS specific files
**/.DS_Store
# Auto-generated context files
CLAUDE.md

18
.golangci.yml Normal file
View File

@ -0,0 +1,18 @@
# golangci-lint configuration file
# See https://golangci-lint.run/usage/configuration/
version: "2"
linters:
exclusions:
paths: []
formatters:
enable:
- gci
- gofumpt
settings:
gci:
sections:
- standard
- default
- localmodule

View File

@ -0,0 +1,74 @@
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
"name": "io.github.safedep/vet-mcp",
"title": "SafeDep Vet MCP",
"description": "Protect your AI agents and IDEs from malicious open-source packages.",
"version": "VERSION_FROM_ENV",
"websiteUrl": "https://safedep.io",
"repository": {
"url": "https://github.com/safedep/vet",
"source": "github"
},
"icons": [
{
"src": "https://raw.githubusercontent.com/safedep/.github/9275c7d1b59f718d73e47cecd93df92e7bfbea25/assets/logo/safedep-logo-darkshade.svg",
"mimeType": "image/svg+xml",
"sizes": [
"48x48",
"96x96"
],
"theme": "light"
},
{
"src": "https://raw.githubusercontent.com/safedep/.github/9275c7d1b59f718d73e47cecd93df92e7bfbea25/assets/logo/safedep-logo.svg",
"mimeType": "image/svg+xml",
"sizes": [
"48x48",
"96x96"
],
"theme": "dark"
}
],
"packages": [
{
"registryType": "oci",
"identifier": "ghcr.io/safedep/vet:vVERSION_FROM_ENV",
"runtimeHint": "docker",
"runtimeArguments": [
{
"type": "named",
"name": "--rm",
"value": ""
},
{
"type": "named",
"name": "-i",
"value": ""
}
],
"packageArguments": [
{
"type": "positional",
"value": "-s"
},
{
"type": "named",
"name": "-l",
"value": "/tmp/vet-mcp.log"
},
{
"type": "positional",
"value": "server"
},
{
"type": "positional",
"value": "mcp"
}
],
"transport": {
"type": "stdio"
}
}
]
}

View File

@ -1,2 +1,2 @@
golang 1.24.1
golang 1.25.1
gitleaks 8.16.4

View File

@ -25,20 +25,21 @@ Create a new issue and add the label "enhancement".
When contributing changes to repository, follow these steps:
1. Ensure tests are passing
2. Ensure you write test cases for new code
3. `Signed-off-by` line is required in commit message (use `-s` flag while committing)
1. If you modified code that requires generation (e.g., enum registrations, ent schemas), run `make generate` and commit the generated files
2. Ensure tests are passing
3. Ensure you write test cases for new code
4. `Signed-off-by` line is required in commit message (use `-s` flag while committing)
## Developer Setup
### Requirements
* Go 1.22+
- Go 1.25.0+
### Install Dependencies
* Install [ASDF](https://asdf-vm.com/)
* Install the development tools
- Install [ASDF](https://asdf-vm.com/)
- Install the development tools
```bash
asdf plugin add golang
@ -46,16 +47,16 @@ asdf plugin add gitleaks
asdf install
```
* Install `lefthook`
- Install git hooks (using Go toolchain)
```bash
go install github.com/evilmartians/lefthook@latest
go tool github.com/evilmartians/lefthook install
```
* Install git hooks
Install `golangci-lint`
```bash
$(go env GOPATH)/bin/lefthook install
```shell
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.5.0
```
### Build
@ -78,11 +79,24 @@ Quick build without regenerating code from API specs
make quick-vet
```
### Generate Code
If you modify code that requires generation (enum registrations in `pkg/analyzer/filterv2/enums.go`, ent schemas in `ent/schema/*.go`), run:
```bash
make generate
```
**Important**: Generated files must be committed to the repository. CI will fail if generated code is out of sync.
### Format Code
```bash
golangci-lint fmt
```
### Run Tests
```bash
make test
```

View File

@ -1,30 +1,43 @@
FROM --platform=$BUILDPLATFORM golang:1.24-bullseye@sha256:3c669c8fed069d80d199073b806243c4bf79ad117b797b96f18177ad9c521cff AS build
# Original: golang:1.24-bullseye
FROM --platform=$BUILDPLATFORM golang:1.25-bookworm@sha256:c4bc0741e3c79c0e2d47ca2505a06f5f2a44682ada94e1dba251a3854e60c2bd AS build
WORKDIR /build
# Install cross-compilation tools
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
&& rm -rf /var/lib/apt/lists/*
COPY go.mod go.sum ./
RUN go mod download
COPY . .
ARG TARGETPLATFORM
ENV CGO_ENABLED=1
RUN make quick-vet
# Set up cross-compilation environment based on target platform
RUN case "${TARGETPLATFORM}" in \
"linux/amd64") \
CC=gcc CXX=g++ GOOS=linux GOARCH=amd64 make quick-vet ;; \
"linux/arm64") \
CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++ GOOS=linux GOARCH=arm64 make quick-vet ;; \
*) echo "Unsupported platform: ${TARGETPLATFORM}" && exit 1 ;; \
esac
FROM debian:11-slim@sha256:e4b93db6aad977a95aa103917f3de8a2b16ead91cf255c3ccdb300c5d20f3015
# Original: debian:11-slim
FROM debian:12-slim@sha256:b1a741487078b369e78119849663d7f1a5341ef2768798f7b7406c4240f86aef
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
ca-certificates git \
&& rm -rf /var/lib/apt/lists/*
ARG TARGETPLATFORM
LABEL org.opencontainers.image.source=https://github.com/safedep/vet
LABEL org.opencontainers.image.description="Open source software supply chain security tool"
LABEL org.opencontainers.image.licenses=Apache-2.0
LABEL io.modelcontextprotocol.server.name="io.github.safedep/vet-mcp"
COPY ./samples/ /vet/samples
COPY --from=build /build/vet /usr/local/bin/vet

View File

@ -8,6 +8,12 @@ all: quick-vet
ent:
go generate ./ent
.PHONY: filterv2-gen
filterv2-gen:
go generate ./pkg/analyzer/filterv2/...
generate: ent filterv2-gen
protoc-install:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

715
README.md
View File

@ -1,403 +1,582 @@
<h1 align="center">
<img alt="SafeDep Vet" src="./docs/assets/vet-logo.png" width="150" />
</h1>
<div align="center">
<img width="3024" height="1964" alt="image" src="./docs/assets/vet-terminal.png" />
<p align="center">
Created and maintained by <b><a href="https://safedep.io/">https://safedep.io</a></b> with contributions from the community 🚀
</p>
<h1>SafeDep VET</h1>
<p><strong>🚀 Enterprise grade open source software supply chain security</strong></p>
<p>
<a href="https://github.com/safedep/vet/releases"><strong>Download</strong></a>
<a href="#-quick-start"><strong>Quick Start</strong></a>
<a href="https://docs.safedep.io/"><strong>Documentation</strong></a>
<a href="#-community"><strong>Community</strong></a>
</p>
</div>
<div align="center">
[![Go Report Card](https://goreportcard.com/badge/github.com/safedep/vet)](https://goreportcard.com/report/github.com/safedep/vet)
![License](https://img.shields.io/github/license/safedep/vet)
![Release](https://img.shields.io/github/v/release/safedep/vet)
[![License](https://img.shields.io/github/license/safedep/vet)](https://github.com/safedep/vet/blob/main/LICENSE)
[![Release](https://img.shields.io/github/v/release/safedep/vet)](https://github.com/safedep/vet/releases)
[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/safedep/vet/badge)](https://api.securityscorecards.dev/projects/github.com/safedep/vet)
[![CodeQL](https://github.com/safedep/vet/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/safedep/vet/actions/workflows/codeql.yml)
[![SLSA 3](https://slsa.dev/images/gh-badge-level3.svg)](https://slsa.dev)
[![Scorecard supply-chain security](https://github.com/safedep/vet/actions/workflows/scorecard.yml/badge.svg)](https://github.com/safedep/vet/actions/workflows/scorecard.yml)
[![Twitter](https://img.shields.io/twitter/follow/safedepio?style=social)](https://twitter.com/intent/follow?screen_name=safedepio)
[![CodeQL](https://github.com/safedep/vet/actions/workflows/codeql.yml/badge.svg?branch=main)](https://github.com/safedep/vet/actions/workflows/codeql.yml)
[![Go Reference](https://pkg.go.dev/badge/github.com/safedep/vet.svg)](https://pkg.go.dev/github.com/safedep/vet)
# 🔍 vet
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/safedep/vet)
`vet` is a tool for **protecting against open source software supply chain attacks**. To adapt to organizational needs, it uses
an opinionated policy expressed as [Common Expressions Language](https://cel.dev/) and extensive
package security metadata including
</div>
- **Code Analysis** to guard against risks that actually matter
- **Vulnerabilities** from [OSV](https://osv.dev)
- **Popularity** based guardrails to prevent unvetted or risky packages
- **Maintenance** status of the package
- **Extended License Attributes** based compliance
- **OpenSSF Scorecard** based 3rd party OSS risk management
- **Direct** and **Transitive** dependency analysis for coverage
---
## 🐞 Malicious Code Analysis
## 🎯 Why vet?
`vet` is integrated with [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis) for real time protection against
malicious open source packages through active code scanning and analysis. [vet-action](https://github.com/safedep/vet-action)
seamlessly integrates `vet` in GitHub Action for proactive guardrails against malicious code from open sources.
> **70-90% of modern software constitute code from open sources** — How do we know if it's safe?
## 🎯 Policy as Code
**vet** is an open source software supply chain security tool built for **developers and security engineers** who need:
`vet` is built for users who intend to enforce guardrails against open source supply chain attacks using their opinionated
policies. Security guardrails can be built by expressing policies as [CEL](https://cel.dev/) which `vet` enforces in CI/CD.
**Next-gen Software Composition Analysis** — Vulnerability and malicious package detection
**Policy as Code** — Express opinionated security policies using [CEL](https://cel.dev/)
**Real-time malicious package detection** — Powered by [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis) active scanning
**Multi-ecosystem support** — npm, PyPI, Maven, Go, Docker, GitHub Actions, and more
**CI/CD native** — Built for DevSecOps workflows with support for GitHub Actions, GitLab CI, and more
**MCP Server** — Run `vet` as a MCP server to vet open source packages from AI suggested code
**Agents** — Run AI agents to query and analyze scan results
## ⚡ Quick Start
## 🔥 vet in action
**Install in seconds:**
![vet Demo](./docs/assets/vet-demo.gif)
```bash
# macOS & Linux
brew install safedep/tap/vet
```
# 🚀 Let's go!
or download a [pre-built binary](https://github.com/safedep/vet/releases)
- [🔍 vet](#-vet)
- [🐞 Malicious Code Analysis](#-malicious-code-analysis)
- [🎯 Policy as Code](#-policy-as-code)
- [🔥 vet in action](#-vet-in-action)
- [🚀 Let's go!](#-lets-go)
- [Getting Started](#getting-started)
- [Running Scan](#running-scan)
- [Scanning Binary Artifacts](#scanning-binary-artifacts)
- [Scanning SBOM](#scanning-sbom)
- [Scanning Github Repositories](#scanning-github-repositories)
- [Scanning Github Organization](#scanning-github-organization)
- [Scanning Package URL](#scanning-package-url)
- [Available Parsers](#available-parsers)
- [Policy as Code](#policy-as-code)
- [Vulnerability](#vulnerability)
- [License](#license)
- [Scorecard](#scorecard)
- [Query Mode](#query-mode)
- [Reporting](#reporting)
- [CI/CD Integration](#cicd-integration)
- [📦 GitHub Action](#-github-action)
- [🚀 GitLab CI](#-gitlab-ci)
- [🐙 Malicious Package Analysis](#-malicious-package-analysis)
- [🔍 Scanning Visual Studio Code Extensions](#-scanning-visual-studio-code-extensions)
- [🔍 Scanning GitHub Actions (or any other GitHub repository)](#-scanning-github-actions-or-any-other-github-repository)
- [🛠️ Advanced Usage](#-advanced-usage)
- [📖 Documentation](#-documentation)
- [🎊 Community](#-community)
- [💻 Development](#-development)
- [Support](#support)
- [Star History](#star-history)
- [🔖 References](#-references)
**Scan your project:**
## Getting Started
```bash
# Scan current directory
vet scan -D .
- Download the binary file for your operating system / architecture from the [Official GitHub Releases](https://github.com/safedep/vet/releases)
# Scan a single file
vet scan -M package-lock.json
- You can also install `vet` using homebrew in MacOS and Linux
# Fail CI on critical vulnerabilities
vet scan -D . --filter 'vulns.critical.exists(p, true)' --filter-fail
# Fail CI on OpenSSF Scorecard requirements
vet scan -D . --filter 'scorecard.scores.Maintained < 5' --filter-fail
# Fail CI if a package is published from a GitHub repository with less than 5 stars
vet scan -D . --filter 'projects.exists(p, p.type == "GITHUB" && p.stars < 5)' --filter-fail
```
## 🔒 Key Features
### 🕵️ **Code Analysis**
Unlike dependency scanners that flood you with noise, `vet` analyzes your **actual code usage** to prioritize real risks. See [dependency usage evidence](https://docs.safedep.io/guides/dependency-usage-identification) for more details.
### 🛡️ **Malicious Package Detection**
Integrated with [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis) for real-time protection against malicious packages in the wild. Free for open source projects. Fallback to _Query Mode_ when API key is not provided. Read more [about malicious package scanning](#-malicious-package-detection-1).
### 📋 **Policy as Code**
Define security policies using CEL expressions to enforce context specific security requirements.
```bash
# Block packages with critical CVEs
vet scan \
--filter 'vulns.critical.exists(p, true)'
# Enforce license compliance
vet scan \
--filter 'licenses.contains_license("GPL-3.0")'
# Enforce OpenSSF Scorecard requirements
# Require minimum OpenSSF Scorecard scores
vet scan \
--filter 'scorecard.scores.Maintained < 5'
```
### 🎯 **Multi-Format Support**
- **Package Managers**: npm, PyPI, Maven, Go, Ruby, Rust, PHP
- **Container Images**: Docker, OCI
- **SBOMs**: CycloneDX, SPDX
- **Binary Artifacts**: JAR files, Python wheels
- **Source Code**: Direct repository scanning
## 🔥 See vet in Action
<div align="center">
<img src="./docs/assets/vet-demo.gif" alt="vet Demo" width="100%" />
</div>
## 🚀 Production Ready Integrations
### 📦 **GitHub Actions**
Zero config security guardrails against vulnerabilities and malicious packages in your CI/CD pipeline
**with your own opinionated policies**:
```yaml
- uses: safedep/vet-action@v1
with:
policy: ".github/vet/policy.yml"
```
See more in [vet-action](https://github.com/safedep/vet-action) documentation.
### 🔧 **GitLab CI**
Enterprise grade scanning with [vet CI Component](https://gitlab.com/explore/catalog/safedep/ci-components/vet):
```yaml
include:
- component: gitlab.com/safedep/ci-components/vet/scan@main
```
### 🐳 **Container Integration**
Run `vet` anywhere, even your internal developer platform or custom CI/CD environment using our container image.
```bash
docker run --rm -v $(pwd):/app ghcr.io/safedep/vet:latest scan -D /app
```
## 📚 Table of Contents
- [🎯 Why vet?](#-why-vet)
- [⚡ Quick Start](#-quick-start)
- [🔒 Key Features](#-key-features)
- [🕵️ **Code Analysis**](#-code-analysis)
- [🛡️ **Malicious Package Detection**](#-malicious-package-detection)
- [📋 **Policy as Code**](#-policy-as-code)
- [🎯 **Multi-Format Support**](#-multi-format-support)
- [🔥 See vet in Action](#-see-vet-in-action)
- [🚀 Production Ready Integrations](#-production-ready-integrations)
- [📦 **GitHub Actions**](#-github-actions)
- [🔧 **GitLab CI**](#-gitlab-ci)
- [🐳 **Container Integration**](#-container-integration)
- [📚 Table of Contents](#-table-of-contents)
- [📦 Installation Options](#-installation-options)
- [🍺 **Homebrew (Recommended)**](#-homebrew-recommended)
- [📥 **Direct Download**](#-direct-download)
- [🐹 **Go Install**](#-go-install)
- [🐳 **Container Image**](#-container-image)
- [⚙️ **Verify Installation**](#-verify-installation)
- [🎮 Advanced Usage](#-advanced-usage)
- [🔍 **Scanning Options**](#-scanning-options)
- [🎯 **Policy Enforcement Examples**](#-policy-enforcement-examples)
- [🔧 **SBOM Support**](#-sbom-support)
- [📊 **Query Mode \& Data Persistence**](#-query-mode--data-persistence)
- [📊 Reporting](#-reporting)
- [📋 **Report Formats**](#-report-formats)
- [🎯 **Report Examples**](#-report-examples)
- [🤖 **MCP Server**](#-mcp-server)
- [🤖 **Agents**](#-agents)
- [🛡️ Malicious Package Detection](#-malicious-package-detection-1)
- [🚀 **Quick Setup**](#-quick-setup)
- [🎯 **Advanced Malicious Package Analysis**](#-advanced-malicious-package-analysis)
- [🔒 **Security Features**](#-security-features)
- [📊 Privacy and Telemetry](#-privacy-and-telemetry)
- [🎊 Community \& Support](#-community--support)
- [🌟 **Join the Community**](#-join-the-community)
- [💡 **Get Help \& Share Ideas**](#-get-help--share-ideas)
- [⭐ **Star History**](#-star-history)
- [🙏 **Built With Open Source**](#-built-with-open-source)
## 📦 Installation Options
### 🍺 **Homebrew (Recommended)**
```bash
brew tap safedep/tap
brew install safedep/tap/vet
```
- Alternatively, build from source
### 📥 **Direct Download**
> Ensure $(go env GOPATH)/bin is in your $PATH
See [releases](https://github.com/safedep/vet/releases) for the latest version.
### 🐹 **Go Install**
```bash
go install github.com/safedep/vet@latest
```
- Also available as a container image
### 🐳 **Container Image**
```bash
docker run --rm -it ghcr.io/safedep/vet:latest version
# Quick test
docker run --rm ghcr.io/safedep/vet:latest version
# Scan local directory
docker run --rm -v $(pwd):/workspace ghcr.io/safedep/vet:latest scan -D /workspace
```
> **Note:** Container image is built for x86_64 Linux only. Use a
> [pre-built binary](https://github.com/safedep/vet/releases) or
> build from source for other platforms.
### Running Scan
- Run `vet` to identify risks by scanning a directory
### ⚙️ **Verify Installation**
```bash
vet scan -D /path/to/repository
vet version
# Should display version and build information
```
![vet scan directory](./docs/assets/vet-scan-directory.png)
## 🎮 Advanced Usage
- Run `vet` to scan specific (supported) package manifests
### 🔍 **Scanning Options**
<table>
<tr>
<td width="50%">
**📁 Directory Scanning**
```bash
vet scan -M /path/to/pom.xml
vet scan -M /path/to/requirements.txt
vet scan -M /path/to/package-lock.json
# Scan current directory
vet scan
# Scan a given directory
vet scan -D /path/to/project
# Resolve and scan transitive dependencies
vet scan -D . --transitive
```
**Note:** `--lockfiles` is generalized to `-M` or `--manifests` to support additional
types of package manifests or other artifacts in future.
#### Scanning Binary Artifacts
- Scan a Java JAR file
**📄 Manifest Files**
```bash
vet scan -M /path/to/app.jar
# Package managers
vet scan -M package-lock.json
vet scan -M requirements.txt
vet scan -M pom.xml
vet scan -M go.mod
vet scan -M Gemfile.lock
```
> Suitable for scanning bootable JARs with embedded dependencies
</td>
<td width="50%">
- Scan a directory with JAR files
```bash
vet scan -D /path/to/jars --type jar
```
#### Scanning SBOM
- Scan an SBOM in [CycloneDX](https://cyclonedx.org/) format
```bash
vet scan -M /path/to/cyclonedx-sbom.json --type bom-cyclonedx
```
- Scan an SBOM in [SPDX](https://spdx.dev/) format
```bash
vet scan -M /path/to/spdx-sbom.json --type bom-spdx
```
**Note:** `--type` is a generalized version of `--lockfile-as` to support additional
artifact types in future.
> **Note:** SBOM scanning feature is currently in experimental stage
#### Scanning Github Repositories
- Setup github access token to scan private repo
**🐙 GitHub Integration**
```bash
# Setup GitHub access
vet connect github
# Scan repositories
vet scan --github https://github.com/user/repo
# Organization scanning
vet scan --github-org https://github.com/org
```
Alternatively, set `GITHUB_TOKEN` environment variable with [Github PAT](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens)
- To scan remote Github repositories, including private ones
**📦 Artifact Scanning**
```bash
vet scan --github https://github.com/safedep/vet
# Container images
vet scan --image nginx:latest
vet scan --image /path/to/image-saved-file.tar
# Binary artifacts
vet scan -M app.jar
vet scan -M package.whl
```
**Note:** You may need to enable [Dependency Graph](https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-the-dependency-graph) at repository or organization level for Github repository scanning to work.
</td>
</tr>
</table>
#### Scanning Github Organization
> You must setup the required access for scanning private repositories
> before scanning organizations
### 🎯 **Policy Enforcement Examples**
```bash
vet scan --github-org https://github.com/safedep
# Security-first scanning
vet scan -D . \
--filter 'vulns.critical.exists(p, true) || vulns.high.exists(p, true)' \
--filter-fail
# License compliance
vet scan -D . \
--filter 'licenses.contains_license("GPL-3.0")' \
--filter-fail
# OpenSSF Scorecard requirements
vet scan -D . \
--filter 'scorecard.scores.Maintained < 5' \
--filter-fail
# Popularity-based filtering
vet scan -D . \
--filter 'projects.exists(p, p.type == "GITHUB" && p.stars < 50)' \
--filter-fail
```
> **Note:** `vet` will block and wait if it encounters Github secondary rate limit.
#### Scanning Package URL
- To scan a [purl](https://github.com/package-url/purl-spec)
### 🔧 **SBOM Support**
```bash
vet scan --purl pkg:/gem/nokogiri@1.10.4
# Scan a CycloneDX SBOM
vet scan -M sbom.json --type bom-cyclonedx
# Scan a SPDX SBOM
vet scan -M sbom.spdx.json --type bom-spdx
# Generate SBOM output
vet scan -D . --report-cdx=output.sbom.json
# Package URL scanning
vet scan --purl pkg:npm/lodash@4.17.21
```
#### Available Parsers
### 📊 **Query Mode & Data Persistence**
- List supported package manifest parsers including experimental modules
For large codebases and repeated analysis:
```bash
vet scan parsers --experimental
# Scan once, query multiple times
vet scan -D . --json-dump-dir ./scan-data
# Query with different filters
vet query --from ./scan-data \
--filter 'vulns.critical.exists(p, true)'
# Generate focused reports
vet query --from ./scan-data \
--filter 'licenses.contains_license("GPL")' \
--report-json license-violations.json
```
## Policy as Code
## 📊 Reporting
`vet` uses [Common Expressions Language](https://github.com/google/cel-spec)
(CEL) as the policy language. Policies can be defined to build guardrails
preventing introduction of insecure components.
**vet** generate reports that are tailored for different stakeholders:
### Vulnerability
### 📋 **Report Formats**
- Run `vet` and fail if a critical or high vulnerability was detected
<table>
<tr>
<td width="30%"><strong>🔍 For Security Teams</strong></td>
<td width="70%">
```bash
vet scan -D /path/to/code \
--filter 'vulns.critical.exists(p, true) || vulns.high.exists(p, true)' \
--filter-fail
# SARIF for GitHub Security tab
vet scan -D . --report-sarif=report.sarif
# JSON for custom tooling
vet scan -D . --report-json=report.json
# CSV for spreadsheet analysis
vet scan -D . --report-csv=report.csv
# HTML for web-based analysis
vet scan -D . --report-html=report.html
```
### License
- Run `vet` and fail if a package with a specific license was detected
</td>
</tr>
<tr>
<td><strong>📖 For Developers</strong></td>
<td>
```bash
vet scan -D /path/to/code \
--filter 'licenses.exists(p, "GPL-2.0")' \
--filter-fail
# Markdown reports for PRs
vet scan -D . --report-markdown=report.md
# Console summary (default)
vet scan -D . --report-summary
```
**Note:** Using `licenses.contains_license(...)` is recommended for license matching due
to its support for SPDX expressions.
- `vet` supports [SPDX License Expressions](https://spdx.github.io/spdx-spec/v2.3/SPDX-license-expressions/) at package license and policy level
</td>
</tr>
<tr>
<td><strong>🏢 For Compliance</strong></td>
<td>
```bash
vet scan -D /path/to/code \
--filter 'licenses.contains_license("LGPL-2.1+")' \
--filter-fail
# SBOM generation
vet scan -D . --report-cdx=sbom.json
# Dependency graphs
vet scan -D . --report-graph=dependencies.dot
```
### Scorecard
</td>
</tr>
</table>
- Run `vet` and fail based on [OpenSSF Scorecard](https://securityscorecards.dev/) attributes
### 🎯 **Report Examples**
```bash
vet scan -D /path/to/code \
--filter 'scorecard.scores.Maintained == 0' \
--filter-fail
# Multi-format output
vet scan -D . \
--report-json=report.json \
--report-sarif=report.sarif \
--report-markdown=report.md \
--report-html=report.html
# Focus on specific issues
vet scan -D . \
--filter 'vulns.high.exists(p, true)' \
--report-json=report.json
```
For more examples, refer to [documentation](https://docs.safedep.io/advanced/policy-as-code)
### 🤖 **MCP Server**
## Query Mode
- Run scan and dump internal data structures to a file for further querying
**vet** can be used as an MCP server to vet open source packages from AI suggested code.
```bash
vet scan -D /path/to/code --json-dump-dir /path/to/dump
# Start the MCP server with SSE transport
vet server mcp --server-type sse
```
- Filter results using `query` command
```bash
vet query --from /path/to/dump \
--filter 'vulns.critical.exists(p, true) || vulns.high.exists(p, true)'
```
- Generate report from dumped data
```bash
vet query --from /path/to/dump --report-json /path/to/report.json
```
## Reporting
`vet` supports generating reports in multiple formats during `scan` or `query`
execution.
| Format | Description |
|----------|--------------------------------------------------------------------------------|
| Markdown | Human readable report for vulnerabilities, licenses, and more |
| CSV | Export data to CSV format for manual slicing and dicing |
| JSON | Machine readable JSON format following internal schema (maximum data) |
| SARIF | Useful for integration with Github Code Scanning and other tools |
| Graph | Dependency graph in DOT format for risk and package relationship visualization |
| Summary | Default console report with summary of vulnerabilities, licenses, and more |
## CI/CD Integration
### 📦 GitHub Action
- `vet` is available as a GitHub Action, refer to [vet-action](https://github.com/safedep/vet-action)
### 🚀 GitLab CI
- `vet` can be integrated with GitLab CI, refer to [vet CI Component](https://gitlab.com/explore/catalog/safedep/ci-components/vet)
## 🐙 Malicious Package Analysis
`vet` supports scanning for malicious packages using [SafeDep Cloud API](https://docs.safedep.io/cloud/malware-analysis)
which requires an API key.
- To setup an API key for malicious package scanning
For more details, see [vet MCP Server](./docs/mcp.md) documentation.
### 🤖 **Agents**
See [vet Agents](./docs/agent.md) documentation for more details.
## 🛡️ Malicious Package Detection
**Malicious package detection through active scanning and code analysis** powered by
[SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis). `vet` requires an API
key for active scanning of unknown packages. When API key is not provided, `vet` will
fallback to _Query Mode_ which detects known malicious packages from [SafeDep](https://safedep.io)
and [OSV](https://osv.dev) databases.
- Grab a free API key by running `vet cloud quickstart`
- API access is free forever for open source projects
- No proprietary code is collected for malicious package detection
- Only open source package scanning from public repositories is supported
### 🚀 **Quick Setup**
> Malicious package detection requires an API key for [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis).
```bash
# One-time setup
vet cloud quickstart
# Enable malware scanning
vet scan -D . --malware
# Query for known malicious packages without API key
vet scan -D . --malware-query
```
- Run a scan and check for malicious packages
Example malicious packages detected and reported by [SafeDep Cloud](https://docs.safedep.io/cloud/malware-analysis)
malicious package detection:
- [MAL-2025-3541: express-cookie-parser](https://safedep.io/malicious-npm-package-express-cookie-parser/)
- [MAL-2025-4339: eslint-config-airbnb-compat](https://safedep.io/digging-into-dynamic-malware-analysis-signals/)
- [MAL-2025-4029: ts-runtime-compat-check](https://safedep.io/digging-into-dynamic-malware-analysis-signals/)
- [MAL-2025-2227: nyc-config](https://safedep.io/nyc-config-malicious-package/)
### 🎯 **Advanced Malicious Package Analysis**
<table>
<tr>
<td width="50%">
**🔍 Scan packages with malicious package detection enabled**
```bash
vet scan -D /path/to/code --malware
# Real-time scanning
vet scan -D . --malware
# Timeout adjustment
vet scan -D . --malware \
--malware-analysis-timeout=300s
# Batch analysis
vet scan -D . --malware \
--json-dump-dir=./analysis
```
**Note**: `vet` will submit identified packages to SafeDep Cloud for analysis and wait
for a `timeout` period for response. Not all package analysis may be completed
within the timeout period. However, subsequent scans will fetch the results if
available and lead to increased coverage over time. Adjust the timeout using
`--malware-analysis-timeout` flag.
</td>
<td width="50%">
### 🔍 Scanning Visual Studio Code Extensions
- Auto-discover and scan Visual Studio Code extensions in the local system
**🎭 Specialized Scans**
```bash
# VS Code extensions
vet scan --vsx --malware
```
### 🔍 Scanning GitHub Actions (or any other GitHub repository)
- Scan a single GitHub Actions workflow using `inspect` command
```bash
vet inspect malware --purl pkg:github/safedep/vet-action@v1
```
- The same convention can be used to inspect any GitHub repository reference
```bash
vet inspect malware --purl pkg:github/safedep/vet@v1.9.5
```
- Scan all GitHub Actions workflows in a repository
```bash
# GitHub Actions
vet scan -D .github/workflows --malware
# Container Images
vet scan --image nats:2.10 --malware
# Scan a single package and fail if its malicious
vet scan --purl pkg:/npm/nyc-config@10.0.0 --fail-fast
# Active scanning of a single package (requires API key)
vet inspect malware \
--purl pkg:npm/nyc-config@10.0.0
```
**Note:** `vet` will resolve the commit hash for the given version and use it for malware analysis.
This is because GitHub repository tags are mutable and can be changed.
</td>
</tr>
</table>
## 🛠️ Advanced Usage
### 🔒 **Security Features**
- [Threat Hunting with vet](https://docs.safedep.io/advanced/filtering)
- [Policy as Code](https://docs.safedep.io/advanced/policy-as-code)
- [Exceptions and Overrides](https://docs.safedep.io/advanced/exceptions)
- ✅ **Real-time analysis** of packages against known malware databases
- ✅ **Behavioral analysis** using static and dynamic analysis
- ✅ **Zero day protection** through active code scanning
- ✅ **Human in the loop** for triaging and investigation of high impact findings
- ✅ **Real time analysis** with public [analysis log](https://vetpkg.dev/mal)
## 📖 Documentation
## 📊 Privacy and Telemetry
- Refer to [https://safedep.io/docs](https://safedep.io/docs) for the detailed documentation
`vet` collects anonymous usage telemetry to improve the product. **Your code and package information is never transmitted.**
[![vet docs](./docs/assets/vet-docs.png)](https://safedep.io/docs)
```bash
# Disable telemetry (optional)
export VET_DISABLE_TELEMETRY=true
```
## 🎊 Community
## 🎊 Community & Support
First of all, thank you so much for showing interest in `vet`, we appreciate it ❤️
<div align="center">
### 🌟 **Join the Community**
- Join the Discord server using the link - [https://rebrand.ly/safedep-community](https://rebrand.ly/safedep-community)
[![Discord](https://img.shields.io/discord/1090352019379851304?color=7289da&label=Discord&logo=discord&logoColor=white)](https://rebrand.ly/safedep-community)
[![GitHub Discussions](https://img.shields.io/badge/GitHub-Discussions-green?logo=github)](https://github.com/safedep/vet/discussions)
[![Twitter Follow](https://img.shields.io/twitter/follow/safedepio?style=social)](https://twitter.com/safedepio)
[![SafeDep Discord](./docs/assets/safedep-discord.png)](https://rebrand.ly/safedep-community)
</div>
## 💻 Development
### 💡 **Get Help & Share Ideas**
Refer to [CONTRIBUTING.md](CONTRIBUTING.md)
- 🚀 **[Interactive Tutorial](https://killercoda.com/safedep/scenario/101-intro)** - Learn vet hands-on
- 📚 **[Complete Documentation](https://docs.safedep.io/)** - Comprehensive guides
- 💬 **[Discord Community](https://rebrand.ly/safedep-community)** - Real-time support
- 🐛 **[Issue Tracker](https://github.com/safedep/vet/issues)** - Bug reports & feature requests
- 🤝 **[Contributing Guide](CONTRIBUTING.md)** - Join the development
## Support
---
[SafeDep](https://safedep.io) provides enterprise support for `vet`
deployments. Check out [SafeDep Cloud](https://safedep.io) for large scale
deployment and management of `vet` in your organization.
<div align="center">
## Star History
### ⭐ **Star History**
[![Star History Chart](https://api.star-history.com/svg?repos=safedep/vet&type=Date)](https://star-history.com/#safedep/vet&Date)
## 🔖 References
### 🙏 **Built With Open Source**
- https://github.com/google/osv-scanner
- https://github.com/anchore/syft
- https://deps.dev/
- https://securityscorecards.dev/
- https://slsa.dev/
vet stands on the shoulders of giants:
[OSV](https://osv.dev) • [OpenSSF Scorecard](https://securityscorecards.dev/) • [SLSA](https://slsa.dev/) • [OSV-SCALIBR](https://github.com/google/osv-scalibr) • [Syft](https://github.com/anchore/syft)
---
<p><strong>⚡ Secure your supply chain today. Star the repo ⭐ and get started!</strong></p>
Created with ❤️ by [SafeDep](https://safedep.io) and the open source community
</div>
<img referrerpolicy="no-referrer-when-downgrade" src="https://static.scarf.sh/a.png?x-pxid=304d1856-fcb3-4166-bfbf-b3e40d0f1e3b" />

69
agent/agent.go Normal file
View File

@ -0,0 +1,69 @@
// Package agent declares the building blocks for implement vet agent.
package agent
import (
"context"
"github.com/cloudwego/eino/components/tool"
"github.com/cloudwego/eino/schema"
)
type Input struct {
Query string
}
type AnswerFormat string
const (
AnswerFormatMarkdown AnswerFormat = "markdown"
AnswerFormatJSON AnswerFormat = "json"
)
type Output struct {
Answer string
Format AnswerFormat
}
type Memory interface {
AddInteraction(ctx context.Context, interaction *schema.Message) error
GetInteractions(ctx context.Context) ([]*schema.Message, error)
Clear(ctx context.Context) error
}
type Session interface {
ID() string
Memory() Memory
}
// AgentExecutionContext is to pass additional context to the agent
// on a per execution basis. This is required so that an agent can be configured
// and shared with different components while allowing the component to pass
// additional context to the agent.
type AgentExecutionContext struct {
// OnToolCall is called when the agent is about to call a tool.
// This is used for introspection only and not to mutate the agent's behavior.
OnToolCall func(context.Context, Session, Input, string, string) error
}
type AgentExecutionContextOpt func(*AgentExecutionContext)
func WithToolCallHook(fn func(context.Context, Session, Input, string, string) error) AgentExecutionContextOpt {
return func(a *AgentExecutionContext) {
a.OnToolCall = fn
}
}
type Agent interface {
// Execute executes the agent with the given input and returns the output.
// Internally the agent may perform a multi-step operation based on config,
// instructions and available tools.
Execute(context.Context, Session, Input, ...AgentExecutionContextOpt) (Output, error)
}
// AgentToolCallIntrospectionFn is a function that introspects a tool call.
// This is aligned with eino contract.
type AgentToolCallIntrospectionFn func(context.Context /* name */, string /* args */, string) ( /* args */ string, error)
type ToolBuilder interface {
Build(context.Context) ([]tool.BaseTool, error)
}

165
agent/llm.go Normal file
View File

@ -0,0 +1,165 @@
package agent
import (
"context"
"fmt"
"os"
"github.com/cloudwego/eino-ext/components/model/claude"
"github.com/cloudwego/eino-ext/components/model/gemini"
"github.com/cloudwego/eino-ext/components/model/openai"
"github.com/cloudwego/eino/components/model"
"google.golang.org/genai"
)
// Map of fast vs. default models.
var defaultModelMap = map[string]map[string]string{
"openai": {
"default": "gpt-4o",
"fast": "gpt-4o-mini",
},
"claude": {
"default": "claude-sonnet-4-20250514",
"fast": "claude-sonnet-4-20250514",
},
"gemini": {
"default": "gemini-2.5-pro",
"fast": "gemini-2.5-flash",
},
}
type Model struct {
Vendor string
Name string
Fast bool
Client model.ToolCallingChatModel
}
// BuildModelFromEnvironment builds a model from the environment variables.
// The order of preference is:
// 1. OpenAI
// 2. Claude
// 3. Gemini
// 4. Others..
func BuildModelFromEnvironment(fastMode bool) (*Model, error) {
if model, err := buildOpenAIModelFromEnvironment(fastMode); err == nil {
return model, nil
}
if model, err := buildClaudeModelFromEnvironment(fastMode); err == nil {
return model, nil
}
if model, err := buildGeminiModelFromEnvironment(fastMode); err == nil {
return model, nil
}
return nil, fmt.Errorf("no usable LLM found for use with agent")
}
func buildOpenAIModelFromEnvironment(fastMode bool) (*Model, error) {
defaultModel := defaultModelMap["openai"]["default"]
if fastMode {
defaultModel = defaultModelMap["openai"]["fast"]
}
modelName := os.Getenv("OPENAI_MODEL_OVERRIDE")
if modelName == "" {
modelName = defaultModel
}
apiKey := os.Getenv("OPENAI_API_KEY")
if apiKey == "" {
return nil, fmt.Errorf("OPENAI_API_KEY is not set")
}
model, err := openai.NewChatModel(context.Background(), &openai.ChatModelConfig{
Model: modelName,
APIKey: apiKey,
})
if err != nil {
return nil, fmt.Errorf("failed to create openai model: %w", err)
}
return &Model{
Vendor: "openai",
Name: modelName,
Fast: fastMode,
Client: model,
}, nil
}
func buildClaudeModelFromEnvironment(fastMode bool) (*Model, error) {
defaultModel := defaultModelMap["claude"]["default"]
if fastMode {
defaultModel = defaultModelMap["claude"]["fast"]
}
modelName := os.Getenv("ANTHROPIC_MODEL_OVERRIDE")
if modelName == "" {
modelName = defaultModel
}
apiKey := os.Getenv("ANTHROPIC_API_KEY")
if apiKey == "" {
return nil, fmt.Errorf("ANTHROPIC_API_KEY is not set")
}
model, err := claude.NewChatModel(context.Background(), &claude.Config{
Model: modelName,
APIKey: apiKey,
})
if err != nil {
return nil, fmt.Errorf("failed to create claude model: %w", err)
}
return &Model{
Vendor: "claude",
Name: modelName,
Fast: fastMode,
Client: model,
}, nil
}
func buildGeminiModelFromEnvironment(fastMode bool) (*Model, error) {
defaultModel := defaultModelMap["gemini"]["default"]
if fastMode {
defaultModel = defaultModelMap["gemini"]["fast"]
}
modelName := os.Getenv("GEMINI_MODEL_OVERRIDE")
if modelName == "" {
modelName = defaultModel
}
apiKey := os.Getenv("GEMINI_API_KEY")
if apiKey == "" {
return nil, fmt.Errorf("GEMINI_API_KEY is not set")
}
client, err := genai.NewClient(context.Background(), &genai.ClientConfig{
APIKey: apiKey,
})
if err != nil {
return nil, fmt.Errorf("failed to create gemini client: %w", err)
}
model, err := gemini.NewChatModel(context.Background(), &gemini.Config{
Model: modelName,
Client: client,
ThinkingConfig: &genai.ThinkingConfig{
IncludeThoughts: false,
ThinkingBudget: nil,
},
})
if err != nil {
return nil, fmt.Errorf("failed to create gemini model: %w", err)
}
return &Model{
Vendor: "gemini",
Name: modelName,
Fast: fastMode,
Client: model,
}, nil
}

17
agent/llm_test.go Normal file
View File

@ -0,0 +1,17 @@
package agent
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestDefaultModelsMap(t *testing.T) {
t.Run("default model map must have vendor, model, and fast model", func(t *testing.T) {
for vendor, models := range defaultModelMap {
assert.NotEmpty(t, vendor)
assert.NotEmpty(t, models["default"])
assert.NotEmpty(t, models["fast"])
}
})
}

145
agent/mcp.go Normal file
View File

@ -0,0 +1,145 @@
package agent
import (
"context"
"fmt"
"os"
"path/filepath"
einomcp "github.com/cloudwego/eino-ext/components/tool/mcp"
"github.com/cloudwego/eino/components/tool"
"github.com/mark3labs/mcp-go/client"
"github.com/mark3labs/mcp-go/mcp"
)
type McpClientToolBuilderConfig struct {
// Common config
ClientName string
ClientVersion string
// SSE client config
SseURL string
Headers map[string]string
// Stdout client config
SkipDefaultTools bool
SQLQueryToolEnabled bool
SQLQueryToolDBPath string
PackageRegistryToolEnabled bool
// Enable debug mode for the MCP client.
Debug bool
}
type mcpClientToolBuilder struct {
config McpClientToolBuilderConfig
}
var _ ToolBuilder = (*mcpClientToolBuilder)(nil)
// NewMcpClientToolBuilder creates a new MCP client tool builder for `vet` MCP server.
// This basically connects to vet MCP server over SSE or executes the `vet server mcp` command
// to start a MCP server in stdio mode. We maintain loose coupling between the MCP client and the MCP server
// by allowing the client to be configured with a set of flags to enable/disable specific tools. We do this
// to ensure vet MCP contract is not violated and evolves independently. vet Agents will in turn depend on
// vet MCP server for data access.
func NewMcpClientToolBuilder(config McpClientToolBuilderConfig) (*mcpClientToolBuilder, error) {
return &mcpClientToolBuilder{
config: config,
}, nil
}
func (b *mcpClientToolBuilder) Build(ctx context.Context) ([]tool.BaseTool, error) {
var cli *client.Client
var err error
if b.config.SseURL != "" {
cli, err = b.buildSseClient()
if err != nil {
return nil, fmt.Errorf("failed to create sse client: %w", err)
}
} else {
cli, err = b.buildStdioClient()
if err != nil {
return nil, fmt.Errorf("failed to create stdio client: %w", err)
}
}
err = cli.Start(ctx)
if err != nil {
return nil, fmt.Errorf("failed to start mcp client: %w", err)
}
initRequest := mcp.InitializeRequest{}
initRequest.Params.ProtocolVersion = mcp.LATEST_PROTOCOL_VERSION
initRequest.Params.ClientInfo = mcp.Implementation{
Name: b.config.ClientName,
Version: b.config.ClientVersion,
}
_, err = cli.Initialize(ctx, initRequest)
if err != nil {
return nil, fmt.Errorf("failed to initialize mcp client: %w", err)
}
tools, err := einomcp.GetTools(ctx, &einomcp.Config{
Cli: cli,
})
if err != nil {
return nil, fmt.Errorf("failed to get tools: %w", err)
}
return tools, nil
}
func (b *mcpClientToolBuilder) buildSseClient() (*client.Client, error) {
cli, err := client.NewSSEMCPClient(b.config.SseURL, client.WithHeaders(b.config.Headers))
if err != nil {
return nil, fmt.Errorf("failed to create sse client: %w", err)
}
return cli, nil
}
// buildStdioClient is used to start vet mcp server with arguments
// based on the configuration.
func (b *mcpClientToolBuilder) buildStdioClient() (*client.Client, error) {
binaryPath, err := os.Executable()
if err != nil {
return nil, fmt.Errorf("failed to get running binary path: %w", err)
}
// vet-mcp server defaults to stdio transport. See cmd/server/mcp.go
vetMcpServerCommandArgs := []string{"server", "mcp"}
if b.config.Debug {
vetMcpServerLogFile := filepath.Join(os.TempDir(), "vet-mcp-server.log")
vetMcpServerCommandArgs = append(vetMcpServerCommandArgs, "-l", vetMcpServerLogFile)
}
if b.config.SQLQueryToolEnabled {
vetMcpServerCommandArgs = append(vetMcpServerCommandArgs, "--sql-query-tool")
vetMcpServerCommandArgs = append(vetMcpServerCommandArgs, "--sql-query-tool-db-path",
b.config.SQLQueryToolDBPath)
}
if b.config.PackageRegistryToolEnabled {
vetMcpServerCommandArgs = append(vetMcpServerCommandArgs, "--package-registry-tool")
}
if b.config.SkipDefaultTools {
vetMcpServerCommandArgs = append(vetMcpServerCommandArgs, "--skip-default-tools")
}
environmentVariables := []string{}
if b.config.Debug {
environmentVariables = append(environmentVariables, "APP_LOG_LEVEL=debug")
}
cli, err := client.NewStdioMCPClient(binaryPath, environmentVariables, vetMcpServerCommandArgs...)
if err != nil {
return nil, fmt.Errorf("failed to create stdio client: %w", err)
}
return cli, nil
}

45
agent/memory.go Normal file
View File

@ -0,0 +1,45 @@
package agent
import (
"context"
"sync"
"github.com/cloudwego/eino/schema"
)
type simpleMemory struct {
mutex sync.RWMutex
interactions []*schema.Message
}
var _ Memory = (*simpleMemory)(nil)
func NewSimpleMemory() (*simpleMemory, error) {
return &simpleMemory{
interactions: make([]*schema.Message, 0),
}, nil
}
func (m *simpleMemory) AddInteraction(ctx context.Context, interaction *schema.Message) error {
m.mutex.Lock()
defer m.mutex.Unlock()
m.interactions = append(m.interactions, interaction)
return nil
}
func (m *simpleMemory) GetInteractions(ctx context.Context) ([]*schema.Message, error) {
m.mutex.RLock()
defer m.mutex.RUnlock()
return m.interactions, nil
}
func (m *simpleMemory) Clear(ctx context.Context) error {
m.mutex.Lock()
defer m.mutex.Unlock()
m.interactions = make([]*schema.Message, 0)
return nil
}

279
agent/memory_test.go Normal file
View File

@ -0,0 +1,279 @@
package agent
import (
"context"
"fmt"
"sync"
"testing"
"github.com/cloudwego/eino/schema"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNewSimpleMemory(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
assert.NotNil(t, memory)
// Test that initial interactions are empty
ctx := context.Background()
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, 0, len(interactions))
}
func TestSimpleMemory_AddInteraction(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
message := &schema.Message{
Role: schema.User,
Content: "test message",
}
err = memory.AddInteraction(ctx, message)
assert.NoError(t, err)
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, 1, len(interactions))
assert.Equal(t, message, interactions[0])
}
func TestSimpleMemory_AddMultipleInteractions(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
messages := []*schema.Message{
{Role: schema.User, Content: "first message"},
{Role: schema.Assistant, Content: "second message"},
{Role: schema.User, Content: "third message"},
}
for _, msg := range messages {
err = memory.AddInteraction(ctx, msg)
assert.NoError(t, err)
}
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, 3, len(interactions))
for i, msg := range messages {
assert.Equal(t, msg, interactions[i])
}
}
func TestSimpleMemory_GetInteractions(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
// Test empty interactions
interactions, err := memory.GetInteractions(ctx)
assert.NoError(t, err)
assert.NotNil(t, interactions)
assert.Equal(t, 0, len(interactions))
// Add some interactions
message1 := &schema.Message{Role: schema.User, Content: "message 1"}
message2 := &schema.Message{Role: schema.Assistant, Content: "message 2"}
err = memory.AddInteraction(ctx, message1)
require.NoError(t, err)
err = memory.AddInteraction(ctx, message2)
require.NoError(t, err)
interactions, err = memory.GetInteractions(ctx)
assert.NoError(t, err)
assert.Equal(t, 2, len(interactions))
assert.Equal(t, message1, interactions[0])
assert.Equal(t, message2, interactions[1])
}
func TestSimpleMemory_Clear(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
// Add some interactions
message1 := &schema.Message{Role: schema.User, Content: "message 1"}
message2 := &schema.Message{Role: schema.Assistant, Content: "message 2"}
err = memory.AddInteraction(ctx, message1)
require.NoError(t, err)
err = memory.AddInteraction(ctx, message2)
require.NoError(t, err)
// Verify interactions exist
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, 2, len(interactions))
// Clear interactions
err = memory.Clear(ctx)
assert.NoError(t, err)
// Verify interactions are cleared
interactions, err = memory.GetInteractions(ctx)
assert.NoError(t, err)
assert.Equal(t, 0, len(interactions))
}
func TestSimpleMemory_NilInteraction(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
// Test adding nil interaction
err = memory.AddInteraction(ctx, nil)
assert.NoError(t, err)
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, 1, len(interactions))
assert.Nil(t, interactions[0])
}
func TestSimpleMemory_ConcurrentAccess(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
numGoroutines := 100
messagesPerGoroutine := 10
var wg sync.WaitGroup
wg.Add(numGoroutines)
// Concurrent writes
for i := 0; i < numGoroutines; i++ {
go func(goroutineID int) {
defer wg.Done()
for j := 0; j < messagesPerGoroutine; j++ {
message := &schema.Message{
Role: schema.User,
Content: fmt.Sprintf("goroutine-%d-message-%d", goroutineID, j),
}
err := memory.AddInteraction(ctx, message)
assert.NoError(t, err)
}
}(i)
}
wg.Wait()
// Verify all interactions were added
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, numGoroutines*messagesPerGoroutine, len(interactions))
}
func TestSimpleMemory_ConcurrentReadWrite(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
numReaders := 10
numWriters := 10
messagesPerWriter := 5
var wg sync.WaitGroup
wg.Add(numReaders + numWriters)
// Concurrent writers
for i := 0; i < numWriters; i++ {
go func(writerID int) {
defer wg.Done()
for j := 0; j < messagesPerWriter; j++ {
message := &schema.Message{
Role: schema.User,
Content: fmt.Sprintf("writer-%d-message-%d", writerID, j),
}
err := memory.AddInteraction(ctx, message)
assert.NoError(t, err)
}
}(i)
}
// Concurrent readers
for i := 0; i < numReaders; i++ {
go func() {
defer wg.Done()
for j := 0; j < messagesPerWriter; j++ {
interactions, err := memory.GetInteractions(ctx)
assert.NoError(t, err)
assert.NotNil(t, interactions)
// Length can vary due to concurrent writes
assert.GreaterOrEqual(t, len(interactions), 0)
}
}()
}
wg.Wait()
// Final verification
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.Equal(t, numWriters*messagesPerWriter, len(interactions))
}
func TestSimpleMemory_ClearDuringConcurrentAccess(t *testing.T) {
memory, err := NewSimpleMemory()
require.NoError(t, err)
ctx := context.Background()
numWriters := 5
messagesPerWriter := 10
var wg sync.WaitGroup
wg.Add(numWriters + 1) // +1 for the clearer
// Add some initial interactions
for i := 0; i < 5; i++ {
message := &schema.Message{
Role: schema.User,
Content: fmt.Sprintf("initial-message-%d", i),
}
err := memory.AddInteraction(ctx, message)
require.NoError(t, err)
}
// Concurrent writers
for i := 0; i < numWriters; i++ {
go func(writerID int) {
defer wg.Done()
for j := 0; j < messagesPerWriter; j++ {
message := &schema.Message{
Role: schema.User,
Content: fmt.Sprintf("writer-%d-message-%d", writerID, j),
}
err := memory.AddInteraction(ctx, message)
assert.NoError(t, err)
}
}(i)
}
// Clear operation
go func() {
defer wg.Done()
// Clear after some writes have happened
err := memory.Clear(ctx)
assert.NoError(t, err)
}()
wg.Wait()
// Final state check - should be consistent
interactions, err := memory.GetInteractions(ctx)
require.NoError(t, err)
assert.NotNil(t, interactions)
// The exact number depends on timing of clear operation
assert.GreaterOrEqual(t, len(interactions), 0)
}

156
agent/mock.go Normal file
View File

@ -0,0 +1,156 @@
package agent
import (
"context"
"fmt"
"strings"
"github.com/cloudwego/eino/schema"
)
// MockAgent provides a simple implementation of the Agent interface for testing
type mockAgent struct{}
// MockSession is a simple session implementation
type mockSession struct {
sessionID string
memory Memory
}
type mockMemory struct {
interactions []*schema.Message
}
func (m *mockMemory) AddInteraction(ctx context.Context, interaction *schema.Message) error {
m.interactions = append(m.interactions, interaction)
return nil
}
func (m *mockMemory) GetInteractions(ctx context.Context) ([]*schema.Message, error) {
return m.interactions, nil
}
func (m *mockMemory) Clear(ctx context.Context) error {
m.interactions = make([]*schema.Message, 0)
return nil
}
// NewMockAgent creates a new mock agent
func NewMockAgent() *mockAgent {
return &mockAgent{}
}
// NewMockSession creates a new mock session
func NewMockSession() *mockSession {
return &mockSession{
sessionID: "mock-session-1",
memory: &mockMemory{},
}
}
func (s *mockSession) ID() string {
return s.sessionID
}
func (s *mockSession) Memory() Memory {
return s.memory
}
// Execute implements the Agent interface with mock responses
func (m *mockAgent) Execute(ctx context.Context, session Session, input Input, opts ...AgentExecutionContextOpt) (Output, error) {
// Simple mock responses based on input
query := strings.ToLower(input.Query)
var response string
switch {
case strings.Contains(query, "vulnerability") || strings.Contains(query, "vuln"):
response = `🔍 **Vulnerability Analysis**
I found 3 critical vulnerabilities in your dependencies:
**Critical Issues:**
lodash@4.17.19: CVE-2021-23337 (Command Injection)
jackson-databind@2.9.8: CVE-2020-36518 (Deserialization)
urllib3@1.24.1: CVE-2021-33503 (SSRF)
**Recommendation:** Update these packages immediately. All have fixes available in newer versions.
Would you like me to analyze the impact of updating these packages?`
case strings.Contains(query, "malware") || strings.Contains(query, "malicious"):
response = `🚨 **Malware Detection Results**
I detected 2 potentially malicious packages:
**High Risk:**
suspicious-package@1.0.0: Contains obfuscated code and cryptocurrency mining
typosquatted-lib@2.1.0: Mimics popular library with malicious payload
**Action Required:** Remove these packages immediately and scan your systems.
Would you like me to suggest secure alternatives?`
case strings.Contains(query, "secure") || strings.Contains(query, "security"):
response = `🛡 **Security Posture Assessment**
**Overall Security Score: 6.2/10 (Moderate Risk)**
**Summary:**
23 total security issues found
3 critical vulnerabilities requiring immediate action
2 malicious packages detected
15 packages with maintenance concerns
**Priority Actions:**
1. Remove malicious packages (Critical)
2. Update vulnerable dependencies (High)
3. Implement dependency scanning in CI/CD (Medium)
Would you like me to create a detailed remediation plan?`
case strings.Contains(query, "update"):
response = ` **Update Analysis**
Analyzing update recommendations for your dependencies...
**Safe Updates Available:**
12 packages can be safely updated (patch versions)
5 packages have minor version updates with new features
3 packages require major version updates (breaking changes)
**Priority Updates:**
1. lodash: 4.17.19 4.17.21 (Security fix, no breaking changes)
2. urllib3: 1.24.1 1.26.18 (Security fix, minimal risk)
Would you like detailed impact analysis for any specific package?`
default:
response = fmt.Sprintf(`🤖 **Security Analysis**
I'm analyzing your question about: "%s"
I have access to comprehensive security data including:
Vulnerability databases
Malware detection results
Dependency analysis
License compliance
Maintainer health metrics
**Available Analysis Types:**
Security posture assessment
Vulnerability impact analysis
Malware detection
Update recommendations
Compliance checking
What specific aspect would you like me to analyze in detail?`, input.Query)
}
return Output{
Answer: response,
Format: AnswerFormatMarkdown,
}, nil
}

164
agent/react.go Normal file
View File

@ -0,0 +1,164 @@
package agent
import (
"context"
"encoding/json"
"fmt"
"github.com/cloudwego/eino/components/model"
"github.com/cloudwego/eino/components/tool"
einoutils "github.com/cloudwego/eino/components/tool/utils"
"github.com/cloudwego/eino/compose"
"github.com/cloudwego/eino/flow/agent/react"
"github.com/cloudwego/eino/schema"
)
type ReactQueryAgentConfig struct {
MaxSteps int
SystemPrompt string
}
type reactQueryAgent struct {
config ReactQueryAgentConfig
model model.ToolCallingChatModel
tools []tool.BaseTool
}
var _ Agent = (*reactQueryAgent)(nil)
type reactQueryAgentOpt func(*reactQueryAgent)
func WithTools(tools []tool.BaseTool) reactQueryAgentOpt {
return func(a *reactQueryAgent) {
a.tools = tools
}
}
func NewReactQueryAgent(model model.ToolCallingChatModel,
config ReactQueryAgentConfig, opts ...reactQueryAgentOpt,
) (*reactQueryAgent, error) {
a := &reactQueryAgent{
config: config,
model: model,
}
for _, opt := range opts {
opt(a)
}
if a.config.MaxSteps == 0 {
a.config.MaxSteps = 30
}
return a, nil
}
func (a *reactQueryAgent) Execute(ctx context.Context, session Session, input Input, opts ...AgentExecutionContextOpt) (Output, error) {
executionContext := &AgentExecutionContext{}
for _, opt := range opts {
opt(executionContext)
}
agent, err := react.NewAgent(ctx, &react.AgentConfig{
ToolCallingModel: a.model,
ToolsConfig: compose.ToolsNodeConfig{
Tools: a.wrapToolsForError(a.tools),
ToolArgumentsHandler: func(ctx context.Context, name string, arguments string) (string, error) {
// Only allow introspection if the function is provided. Do not allow mutation.
if executionContext.OnToolCall != nil {
_ = executionContext.OnToolCall(ctx, session, input, name, arguments)
}
return arguments, nil
},
},
MaxStep: a.config.MaxSteps,
})
if err != nil {
return Output{}, fmt.Errorf("failed to create react agent: %w", err)
}
var messages []*schema.Message
// Start with the system prompt if available
if a.config.SystemPrompt != "" {
messages = append(messages, &schema.Message{
Role: schema.System,
Content: a.config.SystemPrompt,
})
}
// Add the previous interactions to the messages
interactions, err := session.Memory().GetInteractions(ctx)
if err != nil {
return Output{}, fmt.Errorf("failed to get session memory: %w", err)
}
// TODO: Add a limit to the number of interactions to avoid context bloat
messages = append(messages, interactions...)
// Add the current user query message to the messages
userQueryMsg := &schema.Message{
Role: schema.User,
Content: input.Query,
}
messages = append(messages, userQueryMsg)
// Execute the agent to produce a response
msg, err := agent.Generate(ctx, messages)
if err != nil {
return Output{}, fmt.Errorf("failed to generate response: %w", err)
}
// Add the user query message to the session memory
err = session.Memory().AddInteraction(ctx, userQueryMsg)
if err != nil {
return Output{}, fmt.Errorf("failed to add user query message to session memory: %w", err)
}
// Add the agent response message to the session memory
err = session.Memory().AddInteraction(ctx, msg)
if err != nil {
return Output{}, fmt.Errorf("failed to add response message to session memory: %w", err)
}
return Output{
Answer: a.schemaContent(msg),
}, nil
}
func (a *reactQueryAgent) wrapToolsForError(tools []tool.BaseTool) []tool.BaseTool {
wrappedTools := make([]tool.BaseTool, len(tools))
for i, tool := range tools {
wrappedTools[i] = einoutils.WrapToolWithErrorHandler(tool, func(_ context.Context, err error) string {
errorMessage := map[string]string{
"error": err.Error(),
"suggestion": "Tool call failed, Please try a different approach or check your input.",
}
encodedError, err := json.Marshal(errorMessage)
if err != nil {
return ""
}
return string(encodedError)
})
}
return wrappedTools
}
func (a *reactQueryAgent) schemaContent(msg *schema.Message) string {
content := msg.Content
if len(msg.MultiContent) > 0 {
content = ""
for _, part := range msg.MultiContent {
content += part.Text + "\n"
}
}
return content
}

29
agent/session.go Normal file
View File

@ -0,0 +1,29 @@
package agent
import "github.com/google/uuid"
type session struct {
sessionID string
memory Memory
}
var _ Session = (*session)(nil)
func NewSession(memory Memory) (*session, error) {
return newSessionWithID(uuid.New().String(), memory), nil
}
func newSessionWithID(id string, memory Memory) *session {
return &session{
sessionID: id,
memory: memory,
}
}
func (s *session) ID() string {
return s.sessionID
}
func (s *session) Memory() Memory {
return s.memory
}

651
agent/ui.go Normal file
View File

@ -0,0 +1,651 @@
package agent
import (
"context"
"fmt"
"strings"
"time"
"github.com/charmbracelet/bubbles/textarea"
"github.com/charmbracelet/bubbles/viewport"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/glamour"
"github.com/charmbracelet/lipgloss"
)
// Message types for Bubbletea updates
type statusUpdateMsg struct {
message string
}
type agentResponseMsg struct {
content string
}
type agentThinkingMsg struct {
thinking bool
}
type agentToolCallMsg struct {
toolName string
toolArgs string
}
type thinkingTickMsg struct{}
var (
headerStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("240")).
Padding(0, 1)
inputPromptStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("240"))
inputCursorStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("255"))
inputBorderStyle = lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("240")).
Padding(0, 1)
thinkingStyle = lipgloss.NewStyle().
Foreground(lipgloss.Color("33")).
Bold(true)
)
// AgentUI represents the main TUI model
type agentUI struct {
viewport viewport.Model
textInput textarea.Model
width int
height int
statusMessage string
isThinking bool
messages []uiMessage
ready bool
agent Agent
session Session
config AgentUIConfig
thinkingFrame int
inputHistory []string
historyIndex int
currentInput string
}
// Message represents a chat message
type uiMessage struct {
Role string // "user", "agent", "system"
Content string
Timestamp time.Time
}
// AgentUIConfig defines the configuration for the UI
type AgentUIConfig struct {
Width int
Height int
InitialSystemMessage string
TextInputPlaceholder string
TitleText string
MaxHistory int
// Only for informational purposes.
ModelName string
ModelVendor string
ModelFast bool
}
// DefaultAgentUIConfig returns the opinionated default configuration for the UI
func DefaultAgentUIConfig() AgentUIConfig {
return AgentUIConfig{
Width: 80,
Height: 20,
MaxHistory: 50,
InitialSystemMessage: "Security Agent initialized",
TextInputPlaceholder: "Ask me anything...",
TitleText: "Security Agent",
}
}
// NewAgentUI creates a new agent UI instance
func NewAgentUI(agent Agent, session Session, config AgentUIConfig) *agentUI {
vp := viewport.New(config.Width, config.Height)
ta := textarea.New()
ta.Placeholder = ""
ta.Focus()
ta.SetHeight(1)
ta.SetWidth(80)
ta.CharLimit = 1000
ta.ShowLineNumbers = false
ui := &agentUI{
viewport: vp,
textInput: ta,
statusMessage: "",
messages: []uiMessage{},
agent: agent,
session: session,
config: config,
thinkingFrame: 0,
inputHistory: []string{},
historyIndex: -1,
currentInput: "",
}
ui.addSystemMessage(config.InitialSystemMessage)
return ui
}
// Init implements the tea.Model interface
func (m *agentUI) Init() tea.Cmd {
return tea.Batch(
textarea.Blink,
m.tickThinking(),
)
}
// Update implements the tea.Model interface
func (m *agentUI) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmds []tea.Cmd
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyCtrlC, tea.KeyEsc:
return m, tea.Quit
case tea.KeyEnter:
if m.textInput.Focused() && !m.isThinking {
// Handle user input only if agent is not in thinking mode
userInput := strings.TrimSpace(m.textInput.Value())
if userInput != "" {
// Add to history and reset navigation
m.addToHistory(userInput)
// Add the input to the message list and reset user input field
m.addUserMessage(userInput)
m.resetInputField()
// Check if it's a slash command
if strings.HasPrefix(userInput, "/") {
// Handle slash command
cmd := m.handleSlashCommand(userInput)
if cmd != nil {
cmds = append(cmds, cmd)
}
} else {
// Execute agent query
cmds = append(cmds,
m.setThinking(true),
m.executeAgentQuery(userInput),
)
}
}
}
case tea.KeyTab:
// Switch focus between input and viewport, but not while agent is thinking
if !m.isThinking {
if m.textInput.Focused() {
m.textInput.Blur()
} else {
m.textInput.Focus()
cmds = append(cmds, textarea.Blink)
}
}
case tea.KeyUp, tea.KeyDown:
if m.textInput.Focused() && !m.isThinking {
// Navigate input history when text input is focused
var direction int
if msg.Type == tea.KeyUp {
direction = 1 // Go back in history
} else {
direction = -1 // Go forward in history
}
historyEntry := m.navigateHistory(direction)
m.textInput.SetValue(historyEntry)
m.textInput.CursorEnd()
} else if !m.textInput.Focused() {
// Allow scrolling in viewport when not focused on text input
m.viewport, cmd = m.viewport.Update(msg)
cmds = append(cmds, cmd)
}
case tea.KeyPgUp, tea.KeyPgDown:
// Allow scrolling in viewport when not focused on text input
if !m.textInput.Focused() {
m.viewport, cmd = m.viewport.Update(msg)
cmds = append(cmds, cmd)
}
case tea.KeyHome:
if !m.textInput.Focused() {
m.viewport.GotoTop()
}
case tea.KeyEnd:
if !m.textInput.Focused() {
m.viewport.GotoBottom()
}
}
case tea.WindowSizeMsg:
// Handle window resize
m.width = msg.Width
m.height = msg.Height
// Calculate dimensions for minimal UI
headerHeight := 2 // Header + blank line
inputHeight := 2 // Input area + status
spacing := 1 // Bottom spacing
// Calculate viewport dimensions to maximize output area
viewportHeight := m.height - headerHeight - inputHeight - spacing
// Ensure minimum height
if viewportHeight < 10 {
viewportHeight = 10
}
// Full width utilization
viewportWidth := m.width
// Ensure minimum width
if viewportWidth < 50 {
viewportWidth = 50
}
m.viewport.Width = viewportWidth
m.viewport.Height = viewportHeight
m.textInput.SetWidth(m.width - 3)
// Update content when dimensions change
m.viewport.SetContent(m.renderMessages())
if !m.ready {
m.ready = true
}
case statusUpdateMsg:
m.statusMessage = msg.message
case agentThinkingMsg:
m.isThinking = msg.thinking
// When agent starts thinking, blur the input
if m.isThinking {
m.resetInputField()
m.textInput.Blur()
m.thinkingFrame = 0
cmds = append(cmds, m.tickThinking())
} else {
// Re-focus input when thinking stops
m.textInput.Focus()
cmds = append(cmds, textarea.Blink)
}
case agentResponseMsg:
m.addAgentMessage(msg.content)
cmds = append(cmds, m.setThinking(false))
case agentToolCallMsg:
m.addToolCallMessage(fmt.Sprintf("🔧 %s", msg.toolName), msg.toolArgs)
case thinkingTickMsg:
if m.isThinking {
m.thinkingFrame = (m.thinkingFrame + 1) % 4
cmds = append(cmds, m.tickThinking())
}
}
// Update child components
m.viewport, cmd = m.viewport.Update(msg)
cmds = append(cmds, cmd)
// Only update text input if not thinking
if !m.isThinking {
m.textInput, cmd = m.textInput.Update(msg)
cmds = append(cmds, cmd)
}
return m, tea.Batch(cmds...)
}
// View implements the tea.Model interface
func (m *agentUI) View() string {
if !m.ready {
return "Loading..."
}
if m.width == 0 || m.height == 0 {
return "Initializing..."
}
modelAbility := "fast"
if !m.config.ModelFast {
modelAbility = "slow"
}
modelStatusLine := fmt.Sprintf("%s/%s (%s)", m.config.ModelVendor, m.config.ModelName, modelAbility)
header := headerStyle.Render(fmt.Sprintf("%s %s", m.config.TitleText, modelStatusLine))
content := m.viewport.View()
var thinkingIndicator string
if m.isThinking {
thinkingFrames := []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
spinner := thinkingFrames[m.thinkingFrame%len(thinkingFrames)]
thinkingIndicator = thinkingStyle.Render(fmt.Sprintf("%s thinking...", spinner))
}
var inputArea string
userInput := m.textInput.Value()
cursor := ""
if m.textInput.Focused() && !m.isThinking {
cursor = inputCursorStyle.Render("▊")
}
inputContent := fmt.Sprintf("%s%s%s", inputPromptStyle.Render("> "), userInput, cursor)
inputArea = inputBorderStyle.Width(m.width - 2).Render(inputContent)
statusLine := inputPromptStyle.Render(fmt.Sprintf("** %s | ctrl+c to exit", modelStatusLine))
var components []string
components = append(components, header, "", content, "")
if thinkingIndicator != "" {
components = append(components, thinkingIndicator)
}
components = append(components, inputArea, statusLine)
return lipgloss.JoinVertical(lipgloss.Left, components...)
}
func (m *agentUI) resetInputField() {
m.textInput.Reset()
m.textInput.SetValue("")
m.textInput.CursorStart()
}
func (m *agentUI) addUserMessage(content string) {
m.messages = append(m.messages, uiMessage{
Role: "user",
Content: content,
Timestamp: time.Now(),
})
m.viewport.SetContent(m.renderMessages())
m.viewport.GotoBottom()
}
func (m *agentUI) addAgentMessage(content string) {
m.messages = append(m.messages, uiMessage{
Role: "agent",
Content: content,
Timestamp: time.Now(),
})
m.viewport.SetContent(m.renderMessages())
m.viewport.GotoBottom()
}
func (m *agentUI) addSystemMessage(content string) {
m.messages = append(m.messages, uiMessage{
Role: "system",
Content: content,
Timestamp: time.Now(),
})
m.viewport.SetContent(m.renderMessages())
m.viewport.GotoBottom()
}
func (m *agentUI) addToolCallMessage(toolName string, toolArgs string) {
content := fmt.Sprintf(" %s", toolName)
if toolArgs != "" && toolArgs != "{}" {
content += fmt.Sprintf("\n └─ %s", toolArgs)
}
m.messages = append(m.messages, uiMessage{
Role: "tool",
Content: content,
Timestamp: time.Now(),
})
m.viewport.SetContent(m.renderMessages())
m.viewport.GotoBottom()
}
// renderMessages formats all messages for display
func (m *agentUI) renderMessages() string {
var rendered []string
rendered = append(rendered, "", "")
contentWidth := m.viewport.Width - 2 // Account for internal padding
if contentWidth < 40 {
contentWidth = 40
}
r, err := glamour.NewTermRenderer(
glamour.WithStandardStyle("notty"),
glamour.WithWordWrap(contentWidth),
)
if err != nil {
r = nil
}
for _, msg := range m.messages {
timestamp := msg.Timestamp.Format("15:04:05")
switch msg.Role {
case "user":
userHeaderStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("86")).
Bold(true).
Border(lipgloss.NormalBorder(), false, false, false, true).
BorderForeground(lipgloss.Color("86")).
Padding(0, 1)
userContentStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("255")).
Padding(0, 2)
rendered = append(rendered,
userHeaderStyle.Render(fmt.Sprintf("[%s] → You:", timestamp)),
userContentStyle.Render(msg.Content),
"",
)
case "agent":
var content string
if r != nil {
renderedMarkdown, err := r.Render(msg.Content)
if err == nil {
content = strings.TrimSpace(renderedMarkdown)
} else {
content = msg.Content // Fallback to plain text
}
} else {
content = msg.Content
}
agentHeaderStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("39")).
Bold(true).
Border(lipgloss.NormalBorder(), false, false, false, true).
BorderForeground(lipgloss.Color("39")).
Padding(0, 1)
agentContentStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("255")).
Padding(0, 2)
rendered = append(rendered,
agentHeaderStyle.Render(fmt.Sprintf("[%s] ← Agent:", timestamp)),
agentContentStyle.Render(content),
"",
)
case "system":
systemStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("241")).
Italic(true).
Border(lipgloss.NormalBorder(), false, false, false, true).
BorderForeground(lipgloss.Color("241")).
Padding(0, 1)
rendered = append(rendered,
systemStyle.Render(fmt.Sprintf("[%s] %s", timestamp, msg.Content)),
"",
)
case "tool":
toolStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("245")).
Italic(true).
Faint(true).
Border(lipgloss.NormalBorder(), false, false, false, true).
BorderForeground(lipgloss.Color("245")).
Padding(0, 1)
rendered = append(rendered,
toolStyle.Render(fmt.Sprintf("[%s] %s", timestamp, msg.Content)),
"",
)
}
}
rendered = append(rendered, "", "")
return strings.Join(rendered, "\n")
}
func (m *agentUI) updateStatus(message string) tea.Cmd {
return func() tea.Msg {
return statusUpdateMsg{message: message}
}
}
func (m *agentUI) setThinking(thinking bool) tea.Cmd {
return func() tea.Msg {
return agentThinkingMsg{thinking: thinking}
}
}
func (m *agentUI) executeAgentQuery(userInput string) tea.Cmd {
return func() tea.Msg {
ctx := context.Background()
input := Input{
Query: userInput,
}
toolCallHook := func(_ context.Context, _ Session, _ Input, toolName string, toolArgs string) error {
m.Update(agentToolCallMsg{toolName: toolName, toolArgs: toolArgs})
return nil
}
output, err := m.agent.Execute(ctx, m.session, input, WithToolCallHook(toolCallHook))
if err != nil {
return agentResponseMsg{
content: fmt.Sprintf("❌ **Error**\n\nSorry, I encountered an error while processing your query:\n\n%s", err.Error()),
}
}
return agentResponseMsg{content: output.Answer}
}
}
// StartUI starts the TUI application with the default configuration
func StartUI(agent Agent, session Session) error {
config := DefaultAgentUIConfig()
config.InitialSystemMessage = ""
return StartUIWithConfig(agent, session, config)
}
// StartUIWithConfig starts the TUI application with the provided configuration
func StartUIWithConfig(agent Agent, session Session, config AgentUIConfig) error {
ui := NewAgentUI(agent, session, config)
p := tea.NewProgram(
ui,
tea.WithAltScreen(),
tea.WithMouseCellMotion(),
)
_, err := p.Run()
return err
}
func (m *agentUI) tickThinking() tea.Cmd {
return tea.Tick(150*time.Millisecond, func(time.Time) tea.Msg {
return thinkingTickMsg{}
})
}
// handleSlashCommand processes commands that start with '/'
func (m *agentUI) handleSlashCommand(command string) tea.Cmd {
switch command {
case "/exit":
m.addSystemMessage("Goodbye! Exiting gracefully...")
return tea.Quit
default:
m.addSystemMessage(fmt.Sprintf("Unknown command: %s", command))
return nil
}
}
// addToHistory adds input to history buffer with a maximum of 50 entries
func (m *agentUI) addToHistory(input string) {
// Don't add empty strings or duplicates of the last entry
if input == "" || (len(m.inputHistory) > 0 && m.inputHistory[len(m.inputHistory)-1] == input) {
return
}
m.inputHistory = append(m.inputHistory, input)
// Keep only the last maxHistory entries
if len(m.inputHistory) > m.config.MaxHistory {
m.inputHistory = m.inputHistory[len(m.inputHistory)-m.config.MaxHistory:]
}
// Reset history navigation
m.historyIndex = -1
m.currentInput = ""
}
// navigateHistory moves through input history and returns the selected entry
func (m *agentUI) navigateHistory(direction int) string {
if len(m.inputHistory) == 0 {
return ""
}
// Save current input when starting navigation
if m.historyIndex == -1 {
m.currentInput = m.textInput.Value()
}
// Calculate new index
newIndex := m.historyIndex + direction
// Handle boundaries
if newIndex < -1 {
newIndex = -1
} else if newIndex >= len(m.inputHistory) {
newIndex = len(m.inputHistory) - 1
}
m.historyIndex = newIndex
// Return the appropriate entry
if m.historyIndex == -1 {
return m.currentInput
}
return m.inputHistory[len(m.inputHistory)-1-m.historyIndex]
}

280
agent/ui_test.go Normal file
View File

@ -0,0 +1,280 @@
package agent
import (
"testing"
"time"
tea "github.com/charmbracelet/bubbletea"
"github.com/stretchr/testify/assert"
)
func TestAgentUICreation(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
assert.NotNil(t, ui, "Failed to create AgentUI")
assert.Empty(t, ui.statusMessage, "Expected empty status message")
assert.False(t, ui.isThinking, "UI should not be thinking initially")
assert.Equal(t, 0, ui.thinkingFrame, "Thinking frame should be 0 initially")
// Check that system message was added if config has one
if config.InitialSystemMessage != "" {
assert.NotEmpty(t, ui.messages, "Expected system message to be added if InitialSystemMessage is set")
}
}
func TestDefaultAgentUIConfig(t *testing.T) {
config := DefaultAgentUIConfig()
assert.Equal(t, 80, config.Width, "Expected default width 80")
assert.Equal(t, 20, config.Height, "Expected default height 20")
assert.Equal(t, "Security Agent", config.TitleText, "Expected title 'Security Agent'")
assert.Equal(t, "Ask me anything...", config.TextInputPlaceholder, "Expected placeholder 'Ask me anything...'")
}
func TestMessageManagement(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
initialCount := len(ui.messages)
// Test adding user message
ui.addUserMessage("Test user message")
assert.Equal(t, initialCount+1, len(ui.messages), "Expected message count to increase")
lastMessage := ui.messages[len(ui.messages)-1]
assert.Equal(t, "user", lastMessage.Role, "Expected last message role to be 'user'")
assert.Equal(t, "Test user message", lastMessage.Content, "Expected last message content to be 'Test user message'")
// Test adding agent message
ui.addAgentMessage("Test agent response")
assert.Equal(t, initialCount+2, len(ui.messages), "Expected message count to increase")
lastMessage = ui.messages[len(ui.messages)-1]
assert.Equal(t, "agent", lastMessage.Role, "Expected last message role to be 'agent'")
// Test adding system message
ui.addSystemMessage("System notification")
assert.Equal(t, initialCount+3, len(ui.messages), "Expected message count to increase")
lastMessage = ui.messages[len(ui.messages)-1]
assert.Equal(t, "system", lastMessage.Role, "Expected last message role to be 'system'")
// Test adding tool call message
ui.addToolCallMessage("ScanVulnerabilities", `{"path": "/app"}`)
assert.Equal(t, initialCount+4, len(ui.messages), "Expected message count to increase")
lastMessage = ui.messages[len(ui.messages)-1]
assert.Equal(t, "tool", lastMessage.Role, "Expected last message role to be 'tool'")
}
func TestMessageRendering(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
// Set up viewport dimensions for rendering
ui.viewport.Width = 80
ui.viewport.Height = 20
ui.addUserMessage("How many vulnerabilities?")
ui.addAgentMessage("Found 5 critical vulnerabilities")
rendered := ui.renderMessages()
assert.NotEmpty(t, rendered, "Expected non-empty rendered output")
assert.Contains(t, rendered, "How many vulnerabilities?", "Rendered output should contain user message")
assert.Contains(t, rendered, "Found 5 critical vulnerabilities", "Rendered output should contain agent message")
assert.Contains(t, rendered, "You:", "Rendered output should contain user label")
assert.Contains(t, rendered, "Agent:", "Rendered output should contain agent label")
}
func TestViewportDimensions(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
// Test window resize handling
resizeMsg := tea.WindowSizeMsg{Width: 100, Height: 30}
ui.Update(resizeMsg)
assert.Equal(t, 100, ui.width, "Expected width 100")
assert.Equal(t, 30, ui.height, "Expected height 30")
// Test minimum dimensions enforcement
resizeMsg = tea.WindowSizeMsg{Width: 10, Height: 5}
ui.Update(resizeMsg)
assert.GreaterOrEqual(t, ui.viewport.Width, 50, "Viewport width should be enforced to minimum 50")
assert.GreaterOrEqual(t, ui.viewport.Height, 10, "Viewport height should be enforced to minimum 10")
}
func TestViewRendering(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
config.ModelName = "gpt-4"
config.ModelVendor = "openai"
config.ModelFast = false
ui := NewAgentUI(mockAgent, mockSession, config)
ui.width = 80
ui.height = 24
ui.ready = true
view := ui.View()
assert.Contains(t, view, "Security Agent", "View should contain title")
assert.Contains(t, view, "openai/gpt-4", "View should contain model information")
assert.Contains(t, view, ">", "View should contain input prompt")
assert.Contains(t, view, "ctrl+c to exit", "View should contain exit instruction")
}
func TestThinkingState(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
ui.width = 80
ui.height = 24
ui.ready = true
// Initially not thinking
assert.False(t, ui.isThinking, "UI should not be thinking initially")
// Set thinking state
thinkingMsg := agentThinkingMsg{thinking: true}
ui.Update(thinkingMsg)
assert.True(t, ui.isThinking, "UI should be thinking after agentThinkingMsg")
// Check view contains thinking indicator
view := ui.View()
assert.Contains(t, view, "thinking...", "View should contain thinking indicator when thinking")
// Stop thinking
thinkingMsg = agentThinkingMsg{thinking: false}
ui.Update(thinkingMsg)
assert.False(t, ui.isThinking, "UI should not be thinking after agentThinkingMsg with false")
}
func TestKeyboardHandling(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
ui.width = 80
ui.height = 24
ui.ready = true
var keyMsg tea.KeyMsg
var model tea.Model
var cmd tea.Cmd
// Test Ctrl+C exits immediately
keyMsg = tea.KeyMsg{Type: tea.KeyCtrlC}
_, cmd = ui.Update(keyMsg)
assert.NotNil(t, cmd, "Ctrl+C should return quit command")
// Test Tab key for focus switching when not thinking
ui.textInput.Focus()
keyMsg = tea.KeyMsg{Type: tea.KeyTab}
model, _ = ui.Update(keyMsg)
ui = model.(*agentUI)
assert.False(t, ui.textInput.Focused(), "Tab should blur text input when it's focused")
// Test Enter key handling when not thinking
ui.textInput.Focus()
ui.textInput.SetValue("test message")
initialMessageCount := len(ui.messages)
keyMsg = tea.KeyMsg{Type: tea.KeyEnter}
model, _ = ui.Update(keyMsg)
ui = model.(*agentUI)
assert.Equal(t, initialMessageCount+1, len(ui.messages), "Enter should add user message when input is not empty")
// Note: Input field reset happens when thinking starts, not immediately
// The resetInputField() is called, but the UI state may not reflect it immediately in tests
}
func TestInputFieldReset(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
// Set some input text
ui.textInput.SetValue("test input")
assert.Equal(t, "test input", ui.textInput.Value(), "Input should contain test text")
// Reset input field
ui.resetInputField()
assert.Empty(t, ui.textInput.Value(), "Input should be empty after reset")
}
func TestCommandCreation(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
// Test status update command
cmd := ui.updateStatus("Testing status")
assert.NotNil(t, cmd, "updateStatus should return a non-nil command")
// Test thinking command
cmd = ui.setThinking(true)
assert.NotNil(t, cmd, "setThinking should return a non-nil command")
// Test execute agent query command
cmd = ui.executeAgentQuery("test query")
assert.NotNil(t, cmd, "executeAgentQuery should return a non-nil command")
}
func TestMessageTimestamps(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
before := time.Now()
ui.addUserMessage("Test message")
after := time.Now()
message := ui.messages[len(ui.messages)-1]
assert.True(t, message.Timestamp.After(before) || message.Timestamp.Equal(before), "Message timestamp should be after or equal to before time")
assert.True(t, message.Timestamp.Before(after) || message.Timestamp.Equal(after), "Message timestamp should be before or equal to after time")
}
func TestUIInitialization(t *testing.T) {
mockAgent := NewMockAgent()
mockSession := NewMockSession()
config := DefaultAgentUIConfig()
ui := NewAgentUI(mockAgent, mockSession, config)
// Test Init command
cmd := ui.Init()
assert.NotNil(t, cmd, "Init should return a non-nil command")
// Test initial state before ready
view := ui.View()
assert.Equal(t, "Loading...", view, "View should show loading before ready")
// Test with zero dimensions
ui.ready = true
ui.width = 0
ui.height = 0
view = ui.View()
assert.Equal(t, "Initializing...", view, "View should show initializing with zero dimensions")
}

53
cmd/agent/common.go Normal file
View File

@ -0,0 +1,53 @@
package agent
import (
"context"
"fmt"
"os"
"github.com/charmbracelet/glamour"
"github.com/safedep/vet/agent"
)
func buildModelFromEnvironment() (*agent.Model, error) {
model, err := agent.BuildModelFromEnvironment(fastMode)
if err != nil {
return nil, fmt.Errorf("failed to build LLM model adapter using environment configuration: %w", err)
}
return model, nil
}
func executeAgentPrompt(agentExecutor agent.Agent, session agent.Session, prompt string) error {
output, err := agentExecutor.Execute(context.Background(), session, agent.Input{
Query: prompt,
}, agent.WithToolCallHook(func(ctx context.Context, session agent.Session, input agent.Input, toolName string, toolArgs string) error {
os.Stderr.WriteString(fmt.Sprintf("Tool called: %s with args: %s\n", toolName, toolArgs))
return nil
}))
if err != nil {
return fmt.Errorf("failed to execute agent: %w", err)
}
terminalRenderer, err := glamour.NewTermRenderer(
glamour.WithAutoStyle(),
glamour.WithWordWrap(80),
glamour.WithEmoji(),
)
if err != nil {
return fmt.Errorf("failed to create glamour renderer: %w", err)
}
rendered, err := terminalRenderer.Render(output.Answer)
if err != nil {
return fmt.Errorf("failed to render answer: %w", err)
}
_, err = os.Stdout.WriteString(rendered)
if err != nil {
return fmt.Errorf("failed to write answer: %w", err)
}
return nil
}

34
cmd/agent/main.go Normal file
View File

@ -0,0 +1,34 @@
// Package agent provides a CLI for running agents.
package agent
import "github.com/spf13/cobra"
var (
maxAgentSteps int
// Use a fast model when available. Opinionated. Can be overridden by the
// setting environment variables.
fastMode bool
// User wants the agent to answer a single question and not start the
// interactive agent. Not all agents may support this.
singlePrompt string
)
func NewAgentCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "agent",
Short: "Run an available AI agent",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}
cmd.PersistentFlags().IntVar(&maxAgentSteps, "max-steps", 30, "The maximum number of steps for the agent executor")
cmd.PersistentFlags().StringVarP(&singlePrompt, "prompt", "p", "", "A single prompt to run the agent with")
cmd.PersistentFlags().BoolVar(&fastMode, "fast", false, "Prefer a fast model when available (compromises on advanced reasoning)")
cmd.AddCommand(newQueryAgentCommand())
return cmd
}

107
cmd/agent/query.go Normal file
View File

@ -0,0 +1,107 @@
package agent
import (
"context"
_ "embed"
"fmt"
"github.com/spf13/cobra"
"github.com/safedep/vet/agent"
"github.com/safedep/vet/internal/analytics"
"github.com/safedep/vet/internal/command"
"github.com/safedep/vet/pkg/common/logger"
)
//go:embed query_prompt.md
var querySystemPrompt string
var queryAgentDBPath string
func newQueryAgentCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "query",
Short: "Query agent allows analysis and querying the vet sqlite3 report database",
RunE: func(cmd *cobra.Command, args []string) error {
err := executeQueryAgent()
if err != nil {
logger.Errorf("failed to execute query agent: %v", err)
}
return nil
},
}
cmd.Flags().StringVar(&queryAgentDBPath, "db", "", "The path to the vet sqlite3 report database")
_ = cmd.MarkFlagRequired("db")
return cmd
}
func executeQueryAgent() error {
analytics.TrackAgentQuery()
toolBuilder, err := agent.NewMcpClientToolBuilder(agent.McpClientToolBuilderConfig{
ClientName: "vet-query-agent",
ClientVersion: command.GetVersion(),
SkipDefaultTools: true,
SQLQueryToolEnabled: true,
SQLQueryToolDBPath: queryAgentDBPath,
PackageRegistryToolEnabled: true,
})
if err != nil {
return fmt.Errorf("failed to create MCP client tool builder: %w", err)
}
tools, err := toolBuilder.Build(context.Background())
if err != nil {
return fmt.Errorf("failed to build tools: %w", err)
}
model, err := buildModelFromEnvironment()
if err != nil {
return fmt.Errorf("failed to build LLM model adapter using environment configuration: %w", err)
}
agentExecutor, err := agent.NewReactQueryAgent(model.Client, agent.ReactQueryAgentConfig{
MaxSteps: maxAgentSteps,
SystemPrompt: querySystemPrompt,
}, agent.WithTools(tools))
if err != nil {
return fmt.Errorf("failed to create agent: %w", err)
}
memory, err := agent.NewSimpleMemory()
if err != nil {
return fmt.Errorf("failed to create memory: %w", err)
}
session, err := agent.NewSession(memory)
if err != nil {
return fmt.Errorf("failed to create session: %w", err)
}
if singlePrompt != "" {
err = executeAgentPrompt(agentExecutor, session, singlePrompt)
if err != nil {
return fmt.Errorf("failed to execute agent prompt: %w", err)
}
} else {
uiConfig := agent.DefaultAgentUIConfig()
uiConfig.TitleText = "🔍 Query Agent - Interactive Query Mode"
uiConfig.TextInputPlaceholder = "Ask me anything about your scan data..."
uiConfig.InitialSystemMessage = "🤖 Query Agent initialized. Ask me anything about your dependencies, vulnerabilities and other supply chain risks."
uiConfig.ModelName = model.Name
uiConfig.ModelVendor = model.Vendor
uiConfig.ModelFast = model.Fast
err = agent.StartUIWithConfig(agentExecutor, session, uiConfig)
if err != nil {
return fmt.Errorf("failed to start agent interaction UI: %w", err)
}
}
return nil
}

57
cmd/agent/query_prompt.md Normal file
View File

@ -0,0 +1,57 @@
Your task is to assist the user in finding useful information from vet scan results
available in an sqlite3 database.
To answer user's query, you MUST do the following:
1. **Schema Discovery**: Use the database schema introspection tool to understand the available tables, columns, and relationships
2. **Query Planning**: Analyze the user's question and plan your approach:
- Identify which tables contain the relevant data
- Determine the relationships between tables needed
- Plan the query structure before writing SQL
3. **Query Execution**: Execute your planned query using the database query tool
4. **Result Validation**: Verify the results make sense and answer the user's question
5. **Response Formatting**: Present findings in clear markdown format
GUIDELINES:
* **Query Best Practices**:
- Always use `COUNT(*)` instead of `SELECT *` when determining table sizes
- Use `LIMIT` and `OFFSET` for pagination with large result sets
- Prefer JOINs over subqueries for better performance
- Use aggregate functions (COUNT, SUM, AVG) for statistical queries
* **Data Integrity**:
- NEVER make assumptions about data that you haven't verified through queries
- If a query returns unexpected results, re-examine your approach
- Always check for NULL values and handle them appropriately
- Validate that your query logic matches the user's intent
* **Error Handling**:
- If a query fails, explain the error and try an alternative approach
- If no data is found, clearly state this rather than making assumptions
- When data seems incomplete, acknowledge limitations in your response
IMPORTANT CONSTRAINTS:
* **Prevent Hallucinations**:
- Only report data that you have actually queried from the database
- NEVER invent or assume data points that weren't returned by your queries
- If you're unsure about a result, query the data again to confirm
- Always distinguish between actual data and your interpretation of it
* **User Interaction**:
- Ask for clarification if the user's query is ambiguous
- Provide context about what the data represents (e.g., "This shows vulnerabilities found in your dependencies")
- If you cannot answer with available data, explain what information is missing
* **Response Format**:
- Present tabular data as markdown tables with appropriate headers
- Include summary statistics when relevant (e.g., "Found 15 vulnerabilities across 8 packages")
- Use clear headings to organize complex responses
- Always explain what the data means in the context of security scanning
* **Domain Context**:
- Remember that vet scans analyze software dependencies for security issues
- Common entities include: packages, vulnerabilities, licenses, malware, scorecards
- Explain technical terms that may be unfamiliar to users

View File

@ -3,11 +3,12 @@ package cloud
import (
"time"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
var (
@ -178,7 +179,6 @@ func executeCreateKey() error {
Desc: keyDescription,
ExpiryInDays: keyExpiresIn,
})
if err != nil {
return err
}

View File

@ -7,10 +7,11 @@ import (
"github.com/cli/oauth/api"
"github.com/cli/oauth/device"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
func newCloudLoginCommand() *cobra.Command {

View File

@ -1,8 +1,12 @@
package cloud
import (
"github.com/safedep/vet/internal/auth"
"fmt"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
)
var (
@ -31,12 +35,25 @@ func NewCloudCommand() *cobra.Command {
cmd.AddCommand(newCloudLoginCommand())
cmd.AddCommand(newRegisterCommand())
cmd.AddCommand(newQueryCommand())
cmd.AddCommand(newPingCommand())
cmd.AddCommand(newWhoamiCommand())
cmd.AddCommand(newKeyCommand())
cmd.AddCommand(newCloudQuickstartCommand())
queryCmd := newQueryCommand()
queryCmd.PreRunE = requireAccessTokenCheck
pingCmd := newPingCommand()
pingCmd.PreRunE = requireAccessTokenCheck
whoamiCmd := newWhoamiCommand()
whoamiCmd.PreRunE = requireAccessTokenCheck
keyCmd := newKeyCommand()
keyCmd.PreRunE = requireAccessTokenCheck
cmd.AddCommand(queryCmd)
cmd.AddCommand(pingCmd)
cmd.AddCommand(whoamiCmd)
cmd.AddCommand(keyCmd)
cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
if tenantDomain != "" {
auth.SetRuntimeCloudTenant(tenantDomain)
@ -45,3 +62,26 @@ func NewCloudCommand() *cobra.Command {
return cmd
}
func requireAccessTokenCheck(cmd *cobra.Command, args []string) error {
// Check if token was obtained/refreshed 5 mins ago
// If > 5 mins, check the access token expiry
// else return
if auth.ShouldCheckAccessTokenExpiry() {
// Check if access token is expired
// If expired (ok), refresh the session
if ok, err := auth.IsAccessTokenExpired(); err != nil {
tenantDomainPlaceholder := auth.TenantDomain()
if tenantDomainPlaceholder == "" {
tenantDomainPlaceholder = "<your-tenant-domain>"
}
ui.PrintError("Automatic token refresh failed, please re-login using `vet cloud login --tenant %s`", tenantDomainPlaceholder)
return fmt.Errorf("failed to check access token expiry: %w", err)
} else if ok {
ui.PrintMsg("Refreshing Access Token")
return auth.RefreshCloudSession()
}
}
return nil
}

View File

@ -3,11 +3,12 @@ package cloud
import (
"time"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
func newPingCommand() *cobra.Command {

View File

@ -4,11 +4,12 @@ import (
"errors"
"sort"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud/query"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
var (

View File

@ -9,11 +9,12 @@ import (
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/controltower/v1"
"github.com/AlecAivazis/survey/v2"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/spf13/cobra"
"google.golang.org/grpc"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud"
"github.com/spf13/cobra"
"google.golang.org/grpc"
)
func newCloudQuickstartCommand() *cobra.Command {
@ -91,7 +92,7 @@ func executeCloudQuickstart() error {
// TODO: We need the ability to auto-detect the project name and version
// and then use that to sync the results to SafeDep Cloud
ui.PrintMsg("✨ Run `vet scan -D /path/to/code --report-sync to scan your code and sync the results to SafeDep Cloud")
ui.PrintMsg("✨ Run `vet scan -D /path/to/code --report-sync` to scan your code and sync the results to SafeDep Cloud")
return nil
}

View File

@ -3,11 +3,12 @@ package cloud
import (
"fmt"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
var (
@ -60,7 +61,6 @@ func registerUserTenant() error {
OrgName: registerOrgName,
OrgDomain: registerOrgDomain,
})
if err != nil {
return err
}

View File

@ -4,11 +4,12 @@ import (
"fmt"
controltowerv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/controltower/v1"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/cloud"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
func newWhoamiCommand() *cobra.Command {

View File

@ -3,6 +3,7 @@ package code
import (
"github.com/safedep/code/core"
"github.com/safedep/code/lang"
"github.com/safedep/vet/pkg/common/logger"
)

View File

@ -1,8 +1,9 @@
package code
import (
"github.com/safedep/vet/internal/command"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/command"
)
var languageCodes []string
@ -10,7 +11,7 @@ var languageCodes []string
func NewCodeCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "code",
Short: "Analyze souce code",
Short: "Analyze source code",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},

View File

@ -4,12 +4,13 @@ import (
"context"
"regexp"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/command"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/code"
"github.com/safedep/vet/pkg/common/logger"
"github.com/safedep/vet/pkg/storage"
"github.com/spf13/cobra"
)
var (

72
cmd/doc/generate.go Normal file
View File

@ -0,0 +1,72 @@
package doc
import (
"fmt"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/spf13/cobra/doc"
)
var (
// markdownOutDir is the output directory for markdown doc files
markdownOutDir string
// manOutDir is the output directory for troff (man markup) doc files
manOutDir string
)
func newGenerateCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "generate",
Short: "Generate docs / manual artifacts",
RunE: func(cmd *cobra.Command, args []string) error {
// we specify the root (see, not parent) command since its the starting point for docs
return runGenerateCommand(cmd.Root())
},
}
cmd.PersistentFlags().StringVar(&markdownOutDir, "markdown", "", "The output directory for markdown doc files")
cmd.PersistentFlags().StringVar(&manOutDir, "man", "", "The output directory for troff (man markup) doc files")
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
// At least one of the output directory is required
if markdownOutDir == "" && manOutDir == "" {
return errors.New("no output directory specified, at least one of the output directory is required")
}
return nil
}
return cmd
}
func runGenerateCommand(rootCmd *cobra.Command) error {
// If markdown directory is specified
if markdownOutDir != "" {
// Create Markdown Manual
if err := doc.GenMarkdownTree(rootCmd, markdownOutDir); err != nil {
return errors.Wrap(err, "failed to generate markdown manual")
}
fmt.Println("Markdown manual doc created in: ", markdownOutDir)
}
// If troff (man markup) directory is specified
if manOutDir != "" {
// Create Troff (man markup) Manual
manHeader := &doc.GenManHeader{
Title: "VET",
Source: "SafeDep",
Manual: "VET Manual",
}
if err := doc.GenManTree(rootCmd, manHeader, manOutDir); err != nil {
return errors.Wrap(err, "failed to generate man (troff) manual")
}
fmt.Println("Troff (man markup) manual doc created in: ", manOutDir)
}
return nil
}

17
cmd/doc/main.go Normal file
View File

@ -0,0 +1,17 @@
package doc
import (
"github.com/spf13/cobra"
)
func NewDocCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "doc",
Short: "Documentation generation internal utilities",
Hidden: true, // Hide from vet public commands and docs itself, since its only build utility
}
cmd.AddCommand(newGenerateCommand())
return cmd
}

View File

@ -12,22 +12,31 @@ import (
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
malysisv1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/services/malysis/v1"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/jedib0t/go-pretty/v6/text"
"github.com/safedep/dry/adapters"
"github.com/safedep/dry/api/pb"
"github.com/safedep/dry/utils"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/analytics"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/common/registry"
vetutils "github.com/safedep/vet/pkg/common/utils"
"github.com/safedep/vet/pkg/malysis"
"github.com/spf13/cobra"
"github.com/safedep/vet/pkg/reporter"
)
var (
malwareAnalysisPackageUrl string
malwareAnalysisTimeout time.Duration
malwareAnalysisReportJSON string
malwareAnalysisReportOSV string
malwareAnalysisNoWait bool
malwareReportOSVFinderName string
malwareReportOSVContacts []string
malwareReportOSVReferenceURL string
malwareReportOSVUseRange bool
)
func newPackageMalwareInspectCommand() *cobra.Command {
@ -51,8 +60,18 @@ func newPackageMalwareInspectCommand() *cobra.Command {
"Timeout for malware analysis")
cmd.Flags().StringVar(&malwareAnalysisReportJSON, "report-json", "",
"Path to save malware analysis report in JSON format")
cmd.Flags().StringVar(&malwareAnalysisReportOSV, "report-osv", "",
"Dir path to save malware analysis report in OSV format and ossf/malicious-packages format")
cmd.Flags().BoolVar(&malwareAnalysisNoWait, "no-wait", false,
"Do not wait for malware analysis to complete")
cmd.Flags().StringVar(&malwareReportOSVFinderName, "report-osv-finder-name", "",
"Finder name for malware analysis report in OSV format")
cmd.Flags().StringSliceVar(&malwareReportOSVContacts, "report-osv-contacts", []string{},
"Contacts for malware analysis report in OSV format (URL, email, etc.)")
cmd.Flags().StringVar(&malwareReportOSVReferenceURL, "report-osv-reference-url", "",
"Custom reference URL for malware analysis report (defaults to app.safedep.io)")
cmd.Flags().BoolVar(&malwareReportOSVUseRange, "report-osv-with-ranges", false,
"Use range-based versioning in OSV report (default: use explicit versions)")
_ = cmd.MarkFlagRequired("purl")
@ -60,6 +79,8 @@ func newPackageMalwareInspectCommand() *cobra.Command {
}
func executeMalwareAnalysis() error {
analytics.TrackCommandInspectMalwareAnalysis()
err := auth.Verify()
if err != nil {
return fmt.Errorf("access to Malicious Package Analysis requires an API key. " +
@ -78,13 +99,37 @@ func executeMalwareAnalysis() error {
return err
}
githubClient, err := adapters.NewGithubClient(adapters.DefaultGitHubClientConfig())
if err != nil {
return fmt.Errorf("failed to create GitHub client: %v", err)
}
versionResolver, err := registry.NewPackageVersionResolver(githubClient)
if err != nil {
return fmt.Errorf("failed to create package version resolver: %v", err)
}
packageVersion := purl.PackageVersion()
// If package version is empty or latest replace it with actual literal latest version
// Reference: https://github.com/safedep/vet/issues/446
if packageVersion.GetVersion() == "" || packageVersion.GetVersion() == "latest" {
ui.PrintMsg("Resolving package version")
version, err := versionResolver.ResolvePackageLatestVersion(purl.Ecosystem(), purl.Name())
if err != nil {
return fmt.Errorf("failed to resolve package latest version: %v", err)
}
ui.PrintSuccess("Resolved package version: %s", version)
packageVersion.Version = version
}
ctx := context.Background()
ctx, cancelFun := context.WithTimeout(ctx, malwareAnalysisTimeout)
defer cancelFun()
// For GitHub Actions packages, we need to resolve the commit hash
if packageVersion.GetPackage().GetEcosystem() == packagev1.Ecosystem_ECOSYSTEM_GITHUB_ACTIONS {
ui.PrintMsg("Resolving commit hash for GitHub Actions package")
@ -115,6 +160,7 @@ func executeMalwareAnalysis() error {
ui.StartSpinner("Waiting for malware analysis to complete")
var report *malysisv1pb.Report
var verificationRecord *malysisv1pb.VerificationRecord
for {
reportResponse, err := service.GetAnalysisReport(ctx, &malysisv1.GetAnalysisReportRequest{
@ -130,6 +176,7 @@ func executeMalwareAnalysis() error {
if reportResponse.GetStatus() == malysisv1.AnalysisStatus_ANALYSIS_STATUS_COMPLETED {
report = reportResponse.GetReport()
verificationRecord = reportResponse.GetVerificationRecord()
break
}
@ -144,20 +191,60 @@ func executeMalwareAnalysis() error {
ui.PrintSuccess("Malware analysis completed successfully")
err = renderToJSON(report)
if err != nil {
ui.PrintError("Failed to render malware analysis report in JSON format: %v", err)
if malwareAnalysisReportJSON != "" {
ui.PrintMsg("Generating JSON report")
err = writeJSONReport(report)
if err != nil {
ui.PrintError("Failed to render malware analysis report in JSON format: %v", err)
}
}
if malwareAnalysisReportOSV != "" {
if !report.GetInference().GetIsMalware() {
ui.PrintWarning("Report is not malware, skipping OSV report generation")
return nil
} else {
ui.PrintMsg("Generating OSV report in: %s", malwareAnalysisReportOSV)
err = writeOSVReport(report)
if err != nil {
ui.PrintError("Failed to render malware analysis report in OSV format: %v", err)
}
}
}
return renderMalwareAnalysisReport(malwareAnalysisPackageUrl,
analyzePackageResponse.GetAnalysisId(), report)
analyzePackageResponse.GetAnalysisId(), report, verificationRecord)
}
func renderToJSON(report *malysisv1pb.Report) error {
if malwareAnalysisReportJSON == "" {
return nil
func writeOSVReport(report *malysisv1pb.Report) error {
err := os.MkdirAll(malwareAnalysisReportOSV, 0o755)
if err != nil {
return fmt.Errorf("failed to create directory: %v", err)
}
generator, err := malysis.NewOpenSSFMaliciousPackageReportGenerator(malysis.OpenSSFMaliciousPackageReportGeneratorConfig{
Dir: malwareAnalysisReportOSV,
})
if err != nil {
return fmt.Errorf("failed to create OpenSSF malicious package report generator: %v", err)
}
err = generator.GenerateReport(context.Background(), report, malysis.OpenSSFMaliciousPackageReportParams{
FinderName: malwareReportOSVFinderName,
Contacts: malwareReportOSVContacts,
ReferenceURL: malwareReportOSVReferenceURL,
UseRange: malwareReportOSVUseRange,
})
if err != nil {
return fmt.Errorf("failed to generate OpenSSF malicious package report: %v", err)
}
return nil
}
func writeJSONReport(report *malysisv1pb.Report) error {
data, err := utils.ToPbJson(report, " ")
if err != nil {
return err
@ -166,7 +253,9 @@ func renderToJSON(report *malysisv1pb.Report) error {
return os.WriteFile(malwareAnalysisReportJSON, []byte(data), 0o644)
}
func renderMalwareAnalysisReport(purl string, analysisId string, report *malysisv1pb.Report) error {
func renderMalwareAnalysisReport(purl string, analysisId string,
report *malysisv1pb.Report, vr *malysisv1pb.VerificationRecord,
) error {
ui.PrintMsg("Malware analysis report for package: %s", purl)
tbl := table.NewWriter()
@ -175,9 +264,13 @@ func renderMalwareAnalysisReport(purl string, analysisId string, report *malysis
tbl.AppendHeader(table.Row{"Package URL", "Status", "Confidence"})
status := text.FgHiGreen.Sprint("SAFE")
status := reporter.InfoBgText(" SAFE ")
if report.GetInference().GetIsMalware() {
status = text.FgHiRed.Sprint("MALWARE")
if vr != nil && vr.IsMalware {
status = reporter.CriticalBgText(" MALICIOUS ")
} else {
status = reporter.WarningBgText(" SUSPICIOUS ")
}
}
confidence := report.GetInference().GetConfidence().String()
@ -187,8 +280,8 @@ func renderMalwareAnalysisReport(purl string, analysisId string, report *malysis
tbl.Render()
fmt.Println()
fmt.Println(text.FgHiYellow.Sprintf("** The full report is available at: %s",
reportVisualizationUrl(analysisId)))
fmt.Println(reporter.WarningText(fmt.Sprintf("** The full report is available at: %s",
reportVisualizationUrl(analysisId))))
fmt.Println()
return nil

17
cmd/server/main.go Normal file
View File

@ -0,0 +1,17 @@
package server
import "github.com/spf13/cobra"
func NewServerCommand() *cobra.Command {
cmd := cobra.Command{
Use: "server",
Short: "Start available servers",
RunE: func(cmd *cobra.Command, args []string) error {
return cmd.Help()
},
}
cmd.AddCommand(newMcpServerCommand())
return &cmd
}

195
cmd/server/mcp.go Normal file
View File

@ -0,0 +1,195 @@
package server
import (
"fmt"
"os"
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/insights/v2/insightsv2grpc"
"buf.build/gen/go/safedep/api/grpc/go/safedep/services/malysis/v1/malysisv1grpc"
"github.com/safedep/dry/adapters"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/auth"
"github.com/safedep/vet/mcp"
"github.com/safedep/vet/mcp/server"
"github.com/safedep/vet/mcp/tools"
"github.com/safedep/vet/pkg/common/logger"
)
var (
mcpServerSseServerAddr string
mcpServerServerType string
skipDefaultTools bool
registerVetSQLQueryTool bool
vetSQLQueryToolDBPath string
registerPackageRegistryTool bool
sseServerAllowedOrigins []string
sseServerAllowedHosts []string
)
func newMcpServerCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "mcp",
Short: "Start the MCP server",
RunE: func(cmd *cobra.Command, args []string) error {
err := startMcpServer()
if err != nil {
logger.Errorf("Failed to start server: %v", err)
os.Exit(1)
}
return nil
},
}
cmd.Flags().StringVar(&mcpServerSseServerAddr, "sse-server-addr", "localhost:9988", "The address to listen for SSE connections")
cmd.Flags().StringVar(&mcpServerServerType, "server-type", "stdio", "The type of server to start (stdio, sse)")
cmd.Flags().StringSliceVar(
&sseServerAllowedOrigins,
"sse-allowed-origins",
nil,
"List of allowed origin prefixes for SSE connections. By default, we allow http://localhost:, http://127.0.0.1: and https://localhost:.",
)
cmd.Flags().StringSliceVar(
&sseServerAllowedHosts,
"sse-allowed-hosts",
nil,
"List of allowed hosts for SSE connections. By default, we allow localhost:9988, 127.0.0.1:9988 and [::1]:9988.",
)
// We allow skipping default tools to allow for custom tools to be registered when the server starts.
// This is useful for agents to avoid unnecessary tool registration.
cmd.Flags().BoolVar(&skipDefaultTools, "skip-default-tools", false, "Skip registering default tools")
// Options to register sqlite3 query tool
cmd.Flags().BoolVar(&registerVetSQLQueryTool, "sql-query-tool", false, "Register the vet report query by SQL tool (requires database path)")
cmd.Flags().StringVar(&vetSQLQueryToolDBPath, "sql-query-tool-db-path", "", "The path to the vet SQLite3 database file")
// Options to register package registry tool
cmd.Flags().BoolVar(&registerPackageRegistryTool, "package-registry-tool", false, "Register the package registry tool")
cmd.PreRunE = func(cmd *cobra.Command, args []string) error {
if registerVetSQLQueryTool && vetSQLQueryToolDBPath == "" {
return fmt.Errorf("database path is required for SQL query tool")
}
return nil
}
return cmd
}
func startMcpServer() error {
driver, err := buildMcpDriver()
if err != nil {
return fmt.Errorf("failed to build MCP driver: %w", err)
}
var mcpSrv server.McpServer
switch mcpServerServerType {
case "stdio":
mcpSrv, err = server.NewMcpServerWithStdioTransport(server.DefaultMcpServerConfig())
case "sse":
config := server.DefaultMcpServerConfig()
// Override with user supplied config
config.SseServerAddr = mcpServerSseServerAddr
// override origins and hosts defaults only if user explicitly set them.
// When explicitly passed as cmd line args, cobra parses
// --sse-allowed-hosts='' as empty slice. Otherwise if not provided,
// sse-allowed-hosts will be nil.
if sseServerAllowedOrigins != nil {
config.SseServerAllowedOriginsPrefix = sseServerAllowedOrigins
}
if sseServerAllowedHosts != nil {
config.SseServerAllowedHosts = sseServerAllowedHosts
}
mcpSrv, err = server.NewMcpServerWithSseTransport(config)
default:
return fmt.Errorf("invalid server type: %s", mcpServerServerType)
}
if err != nil {
return fmt.Errorf("failed to create MCP server: %w", err)
}
if !skipDefaultTools {
err = doRegisterDefaultTools(mcpSrv, driver)
if err != nil {
return fmt.Errorf("failed to register default tools: %w", err)
}
}
if registerVetSQLQueryTool {
err = doRegisterVetSQLQueryTool(mcpSrv)
if err != nil {
return fmt.Errorf("failed to register vet SQL query tool: %w", err)
}
}
if registerPackageRegistryTool {
err = doRegisterPackageRegistryTool(mcpSrv, driver)
if err != nil {
return fmt.Errorf("failed to register package registry tool: %w", err)
}
}
err = mcpSrv.Start()
if err != nil {
return fmt.Errorf("failed to start MCP server: %w", err)
}
return nil
}
func doRegisterDefaultTools(mcpSrv server.McpServer, driver mcp.Driver) error {
return tools.RegisterAll(mcpSrv, driver)
}
func doRegisterVetSQLQueryTool(mcpSrv server.McpServer) error {
tool, err := tools.NewVetSQLQueryTool(vetSQLQueryToolDBPath)
if err != nil {
return fmt.Errorf("failed to create vet SQL query tool: %w", err)
}
return mcpSrv.RegisterTool(tool)
}
func doRegisterPackageRegistryTool(mcpSrv server.McpServer, driver mcp.Driver) error {
err := mcpSrv.RegisterTool(tools.NewPackageRegistryTool(driver))
if err != nil {
return fmt.Errorf("failed to register package registry tool: %w", err)
}
return nil
}
func buildMcpDriver() (mcp.Driver, error) {
insightsConn, err := auth.InsightsV2CommunityClientConnection("vet-mcp-insights")
if err != nil {
return nil, fmt.Errorf("failed to create insights client: %w", err)
}
communityConn, err := auth.MalwareAnalysisCommunityClientConnection("vet-mcp-malware")
if err != nil {
return nil, fmt.Errorf("failed to create community client: %w", err)
}
insightsClient := insightsv2grpc.NewInsightServiceClient(insightsConn)
malysisClient := malysisv1grpc.NewMalwareAnalysisServiceClient(communityConn)
githubAdapter, err := adapters.NewGithubClient(adapters.DefaultGitHubClientConfig())
if err != nil {
return nil, fmt.Errorf("failed to create github client: %w", err)
}
driver, err := mcp.NewDefaultDriver(insightsClient, malysisClient, githubAdapter)
if err != nil {
return nil, fmt.Errorf("failed to create MCP driver: %w", err)
}
return driver, nil
}

60
cmd/server/mcp_test.go Normal file
View File

@ -0,0 +1,60 @@
package server
import (
"context"
"testing"
packagev1 "buf.build/gen/go/safedep/api/protocolbuffers/go/safedep/messages/package/v1"
"github.com/stretchr/testify/assert"
"github.com/safedep/vet/test"
)
func TestMcpDriver(t *testing.T) {
test.EnsureEndToEndTestIsEnabled(t)
driver, err := buildMcpDriver()
if err != nil {
t.Fatalf("failed to build MCP driver: %v", err)
}
t.Run("malysis community service is accessible", func(t *testing.T) {
report, err := driver.GetPackageVersionMalwareReport(context.Background(), &packagev1.PackageVersion{
Package: &packagev1.Package{
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
Name: "express",
},
Version: "4.17.1",
})
assert.NoError(t, err)
assert.NotNil(t, report)
})
t.Run("insights community service is accessible", func(t *testing.T) {
vulns, err := driver.GetPackageVersionVulnerabilities(context.Background(), &packagev1.PackageVersion{
Package: &packagev1.Package{
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
Name: "express",
},
Version: "4.17.1",
})
assert.NoError(t, err)
assert.NotNil(t, vulns)
assert.NotEmpty(t, vulns)
})
t.Run("package registry adapter is accessible", func(t *testing.T) {
res, err := driver.GetPackageLatestVersion(context.Background(), &packagev1.Package{
Ecosystem: packagev1.Ecosystem_ECOSYSTEM_NPM,
Name: "express",
})
assert.NoError(t, err)
assert.NotNil(t, res)
assert.Equal(t, "express", res.GetPackage().GetName())
assert.Equal(t, packagev1.Ecosystem_ECOSYSTEM_NPM, res.GetPackage().GetEcosystem())
assert.NotEmpty(t, res.GetPackage().GetName())
})
}

View File

@ -1,19 +1,19 @@
package main
import (
"context"
"errors"
"fmt"
"os"
"context"
"net/http"
"os"
"github.com/AlecAivazis/survey/v2"
"github.com/cli/oauth/device"
"github.com/spf13/cobra"
"github.com/safedep/vet/internal/connect"
"github.com/safedep/vet/internal/ui"
"github.com/safedep/vet/pkg/common/logger"
"github.com/spf13/cobra"
)
func newConnectCommand() *cobra.Command {
@ -143,7 +143,6 @@ func connectGithubWithDeviceFlow() (string, error) {
ClientID: clientID,
DeviceCode: code,
})
if err != nil {
return "", err
}

40
docs/agent.md Normal file
View File

@ -0,0 +1,40 @@
# Agents
`vet` natively supports AI agents with MCP based integration for tools.
To get started, set an API key for the LLM you want to use. Example:
```bash
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-...
export GEMINI_API_KEY=AIza...
```
> **Note:** You can also set the model to use with `OPENAI_MODEL_OVERRIDE`, `ANTHROPIC_MODEL_OVERRIDE` and `GEMINI_MODEL_OVERRIDE` environment variables to override the default model used by the agent.
## Fast Mode
All agents support a `--fast` flag to use a faster LLM model instead of a slower but more powerful reasoning model. This is only for influencing the default choice of model. It can be overridden by setting model provider specific environment variables such as `OPENAI_MODEL_OVERRIDE`, `ANTHROPIC_MODEL_OVERRIDE` and `GEMINI_MODEL_OVERRIDE`.
## Available Agents
### Query Agent
The query agent helps run query and analysis over vet's sqlite3 reporting database. To use it:
* Run a `vet` scan and generate report in sqlite3 format
```bash
vet scan --insights-v2 -M package-lock.json --report-sqlite3 report.db
```
**Note:** Agents only work with `--insights-v2`
* Start the query agent
```bash
vet agent query --db report.db
```
* Thats it! Start asking questions about the scan results.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 899 KiB

After

Width:  |  Height:  |  Size: 320 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 719 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 624 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 516 KiB

35
docs/doc-generate.md Normal file
View File

@ -0,0 +1,35 @@
# Doc Generate
Docs for `cmd/doc/` command
> [!NOTE]
> This command is `HIDDEN` and not listed in the help output of `vet`. It is used to generate the documentation / manual for the `vet` command line application.
## doc
Documentation generation internal utilities
### Options
```
-h, --help help for doc
```
## doc generate
Generate docs / manual artifacts
```
doc generate [flags]
```
### Options
```
-h, --help help for generate
--man string The output directory for troff (man markup) doc files
--markdown string The output directory for markdown doc files
```
> [!IMPORTANT]
> At least one of the output directory is required

37
docs/manual/_config.yml Normal file
View File

@ -0,0 +1,37 @@
title: SafeDep/vet Manual
description: CLI reference manual for SafeDep/vet. Next-gen software composition analysis and malicious package protection tool.
remote_theme: just-the-docs/just-the-docs@v0.8.0
markdown: kramdown
# Custom Color Schema, defined in _sass/color_schemes/safedep.scss
color_scheme: safedep
# GitHub repo link (appears in top right)
repo_url: https://github.com/safedep/vet
# Aux links (top navigation bar)
aux_links:
"GitHub": https://github.com/safedep/vet
aux_links_new_tab: true
# Heading anchor links (h1, h2, h3...)
heading_anchors: true
# Search functionality
search_enabled: true
search.heading_level: 2
# Logo (if you have one)
logo: "/assets/logo.png"
favicon_ico: "/assets/favicon.png"
# Footer
footer_content: "Copyright &copy; 2025 SafeDep Inc."
# Back to top button
back_to_top: true
back_to_top_text: "Back to top"
plugins:
- jekyll-seo-tag
- jekyll-github-metadata
- jekyll-include-cache
- jekyll-sitemap

View File

@ -0,0 +1,19 @@
// Change Default Theme (purple's variable) to branding color
// SafeDep Brand Color is #0d9488
$safedep-brand: #0d9488;
// This will override the the default color schema
$purple-000: #0c8d75; // A little bit dark in that color for links (much better for links)
$purple-100: #0a7562; // A little more dark on that link color for hover effect
$link-color: $purple-000; // Set Link Color
// Override variables for the .btn-primary button
$btn-primary-color: $safedep-brand;
$btn-primary-bg: $safedep-brand; // Background color of the button
$btn-primary-border: $safedep-brand; // Border color of the button
$btn-hover-color: #10bcad;
$btn-primary-hover-bg: $btn-hover-color; // Background color on hover
$btn-primary-hover-border: $btn-hover-color; // Border color on hover

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
docs/manual/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

28
docs/manual/index.md Normal file
View File

@ -0,0 +1,28 @@
---
title: SafeDep/vet Manual
layout: home
nav_order: 1
---
# SafeDep `vet` CLI manual
[`vet`](https://github.com/safedep/vet) is a free and open source software supply chain security tool. It helps developers and security engineers protect against malicious open source packages and establish policy driven guardrails.
<br />
> _This CLI reference provides detailed documentation for all vet commands, flags, and options._
[Go to CLI Manual](vet.html){: .btn .btn-primary .fs-5 .mb-4 .mb-md-0 .mr-2 }
## `vet` Installation
```bash
brew install safedep/tap/vet
```
See [other installation options](https://github.com/safedep/vet?tab=readme-ov-file#-installation-options)
## Other Resources
Website: <https://safedep.io>
Docs: [https://docs.safedep.io](https://docs.safedep.io/introduction)

266
docs/mcp.md Normal file
View File

@ -0,0 +1,266 @@
# vet MCP Server
[![Install MCP Server](https://cursor.com/deeplink/mcp-install-dark.svg)](cursor://anysphere.cursor-deeplink/mcp/install?name=vet-mcp&config=eyJjb21tYW5kIjoiZG9ja2VyIHJ1biAtLXJtIC1pIGdoY3IuaW8vc2FmZWRlcC92ZXQ6bGF0ZXN0IC1zIC1sIC90bXAvdmV0LW1jcC5sb2cgc2VydmVyIG1jcCJ9)
The `vet` MCP server is designed to run locally using `stdio` or `sse` transports.
It provides tools for MCP clients such as Claude Code, Cursor and others to vet
open source packages before they are used in a project through AI generated code.
`vet` MCP server can protect against [Slopsquatting](https://en.wikipedia.org/wiki/Slopsquatting) attacks, malicious packages,
vulnerabilities and other security risks.
## Supported Ecosystems
`vet` MCP server currently supports the following ecosystems:
- npm
- PyPI
## Usage
Start the MCP server using SSE transport:
```bash
vet server mcp --server-type sse
```
Start the MCP server using stdio transport:
```bash
vet -s -l /tmp/vet-mcp.log server mcp --server-type stdio
```
> Avoid using `stdout` logging as it will interfere with the MCP server output.
### SSE Transport Features
The SSE (Server-Sent Events) transport supports:
- **GET requests**: For establishing SSE connections to receive real-time events
- **HEAD requests**: For endpoint health checks and capability probing (useful for tools like Langchain)
- **POST requests**: For sending messages to the MCP server via the message endpoint
The SSE endpoint returns appropriate headers for HEAD requests without a body, allowing tools to verify endpoint availability and capabilities.
### Security: Host and Origin Guards
For SSE, the server enforces simple, user-configurable guards to reduce the risk
of unauthorized cross-origin access and DNS rebinding attacks.
- **Host guard**: Only allows connections whose `Host` header matches an allowed
host list.
- **Origin guard**: For browser requests, only allows requests whose `Origin`
starts with an allowed prefix.
These checks are on by default with sensible localhost defaults, and you can
customize them with flags when starting the server.
#### Defaults
- **Allowed hosts**: `localhost:9988`, `127.0.0.1:9988`, `[::1]:9988`
- **Allowed origin prefixes**: `http://localhost:`, `http://127.0.0.1:`, `https://localhost:`
Requests that fail the host check are rejected with status `403`, and requests
that fail the origin check are rejected with status `403`.
#### Customize allowed hosts and origins
You can override the defaults using the following flags:
```bash
vet server mcp \
--server-type sse \
--sse-allowed-hosts "localhost:8080,127.0.0.1:8080" \
--sse-allowed-origins "http://localhost:,https://localhost:"
```
If you are running behind a proxy or using a different port, set both lists to
match your environment. For example, when exposing SSE on port 3001:
```bash
vet server mcp \
--server-type sse \
--sse-allowed-hosts "localhost:3001,127.0.0.1:3001" \
--sse-allowed-origins "http://localhost:,http://127.0.0.1:,https://localhost:"
```
With Docker, append the same flags to the container command:
```bash
docker run --rm -i ghcr.io/safedep/vet:latest \
server mcp \
--server-type sse \
--sse-allowed-hosts "localhost:9988,127.0.0.1:9988" \
--sse-allowed-origins "http://localhost:,http://127.0.0.1:,https://localhost:"
```
Tip: Non-browser clients may omit the `Origin` header. Those requests are
allowed as long as the host guard passes.
## Configure MCP Client
> **Note:** The example below uses pre-build docker image. You can build your own by running
> `docker build -t ghcr.io/safedep/vet:latest .`
Add following configuration to your MCP client configuration file:
```json
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"-l",
"/tmp/vet-mcp.log",
"server",
"mcp"
]
}
```
`vet` uses `stdio` by default, if you wish to use SSE transport, add following args: `"--server-type", "sse"`
**Note:** While `docker` containers can help keep the MCP server process isolated, it needs to be periodically updated to the latest version.
Alternatively, you can use `vet` binary directly as an MCP server using `stdio` transport. Use the following command to start the MCP server:
```bash
vet -l /tmp/vet-mcp.log server mcp --server-type stdio
```
### Configure IDE
#### Cursor
Add `vet-mcp` server to either `.cursor/mcp.json` (project specific configuration) or `~/.cursor/mcp.json` (applies to all projects)
```json
{
"mcpServers": {
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"-l",
"/tmp/vet-mcp.log",
"server",
"mcp"
]
}
}
}
```
Add the following to `.cursor/rules/vet-mcp.mdc` file:
```
---
description: vet Open Source Packages using vet MCP server
alwaysApply: true
---
Always use vet-mcp to vet any open source library package suggested by AI generated code before installation.
Follow the rules below to use vet-mcp:
- Try to find the latest version. If not found, it is likely a slopsquatting vulnerability
- Always check for critical vulnerabilities and malware
```
Example usage with Cursor:
![Cursor vet-mcp example](./assets/vet-mcp-cursor.png)
[📄 Cursor MCP server reference](https://docs.cursor.com/context/model-context-protocol#manual-configuration)
#### Visual Studio Code
Add `vet-mcp` server to `.vscode/mcp.json` (project specific configuration)
```json
{
"servers": {
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"-l",
"/tmp/vet-mcp.log",
"server",
"mcp"
]
}
}
}
```
In order to use `vet-mcp` for all projects in Visual Studio Code, add following `mcp` setting in [Visual Studio Code User Settings](https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server-to-your-user-settings) (`settings.json`)
```json
{
"mcp": {
"servers": {
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"-l",
"/tmp/vet-mcp.log",
"server",
"mcp"
]
}
}
}
}
```
Add the following to `.github/copilot-instructions.md` file:
```
Always use vet-mcp to vet any open source library package suggested by AI generated code before installation.
Follow the rules below to use vet-mcp:
- Try to find the latest version. If not found, it is likely a slopsquatting vulnerability
- Always check for critical vulnerabilities and malware
```
Example usage with Visual Studio Code:
![Visual Studio Code vet-mcp example](./assets/vet-mcp-vscode.png)
[📄 Visual Studio Code MCP server reference](https://code.visualstudio.com/docs/copilot/chat/mcp-servers)
#### Claude Code
Add the following to `.mcp.json` in your Claude Code project:
```json
{
"mcpServers": {
"vet-mcp": {
"command": "docker",
"args": [
"run",
"--rm",
"-i",
"ghcr.io/safedep/vet:latest",
"server",
"mcp"
]
}
}
}
```
**Note:** You can also use `vet` binary directly as an MCP server using `stdio` transport.

21
docs/osv-report.md Normal file
View File

@ -0,0 +1,21 @@
## OSV (OSSF) Report
Using `--report-osv` we can generate report for `OSSF` malicious package database.
Usage:
```bash
vet inspect malware --purl ... --report-osv .
```
The value of `--report-osv` is the root of [ossf/malicious-packages](https://github.com/ossf/malicious-packages/) repository,
it automatically places the JSON report in correct location, like `osv/malicious/npm/...`.
Flags:
| Flag | Usage | Default Value |
| -------------------------- | ----------------------------------- | --------------------------------------------- |
| `report-osv-finder-name` | Name of finder | `SafeDep` |
| `report-osv-contacts` | Contact Info, email, website etc | `https://safedep.io` |
| `report-osv-reference-url` | Report Reference URL, like blog etc | `https://app.safedep.io/community/malysis/ID` |
| `report-osv-with-ranges` | Use `ranges` affected property | discrete `versions` |

47
docs/policy-dev.md Normal file
View File

@ -0,0 +1,47 @@
# Policy Engine Development
The policy engine is implemented using [Common Expressions Languages](https://cel.dev).
This development document is ONLY for Policy v2, internally represented
as Filter V2 for naming consistency.
## Enum Constants
Protobuf enums are exposed as integer values in CEL. To improve policy readability, we generate enum constant maps that allow using symbolic names instead of integers.
**Example usage in policies:**
```cel
// Instead of: p.project.type == 1
p.project.type == ProjectSourceType.GITHUB
// Instead of: pkg.ecosystem == 2
pkg.ecosystem == Ecosystem.NPM
```
**How it works:**
- `pkg/analyzer/filterv2/enums.go` registers enums via `RegisteredEnums` by referencing protobuf-generated `Type_value` maps
- `pkg/analyzer/filterv2/enumgen/` generates `enums_generated.go` with constant maps
- Run `go generate ./pkg/analyzer/filterv2/` to regenerate after adding new enums
**Adding new enums:**
1. Add entry to `RegisteredEnums` in `pkg/analyzer/filterv2/enums.go`:
```go
{
Name: "SeverityRisk",
Prefix: "RISK_",
ValueMap: vulnerabilityv1.Severity_Risk_value,
}
```
2. Declare the enum variable in `pkg/analyzer/filterv2/eval.go` `NewEvaluator()`:
```go
cel.Variable("SeverityRisk", cel.MapType(cel.StringType, cel.IntType))
```
3. Run `go generate ./pkg/analyzer/filterv2/`
The generator automatically strips prefixes (e.g., `RISK_CRITICAL``CRITICAL`) and keeps enums synchronized with protobuf definitions.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,17 @@ import (
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/safedep/vet/ent/codesourcefile"
"github.com/safedep/vet/ent/depsusageevidence"
"github.com/safedep/vet/ent/reportdependency"
"github.com/safedep/vet/ent/reportdependencygraph"
"github.com/safedep/vet/ent/reportlicense"
"github.com/safedep/vet/ent/reportmalware"
"github.com/safedep/vet/ent/reportpackage"
"github.com/safedep/vet/ent/reportpackagemanifest"
"github.com/safedep/vet/ent/reportproject"
"github.com/safedep/vet/ent/reportscorecard"
"github.com/safedep/vet/ent/reportscorecardcheck"
"github.com/safedep/vet/ent/reportslsaprovenance"
"github.com/safedep/vet/ent/reportvulnerability"
)
// ent aliases to avoid import conflicts in user's code.
@ -74,8 +85,19 @@ var (
func checkColumn(table, column string) error {
initCheck.Do(func() {
columnCheck = sql.NewColumnCheck(map[string]func(string) bool{
codesourcefile.Table: codesourcefile.ValidColumn,
depsusageevidence.Table: depsusageevidence.ValidColumn,
codesourcefile.Table: codesourcefile.ValidColumn,
depsusageevidence.Table: depsusageevidence.ValidColumn,
reportdependency.Table: reportdependency.ValidColumn,
reportdependencygraph.Table: reportdependencygraph.ValidColumn,
reportlicense.Table: reportlicense.ValidColumn,
reportmalware.Table: reportmalware.ValidColumn,
reportpackage.Table: reportpackage.ValidColumn,
reportpackagemanifest.Table: reportpackagemanifest.ValidColumn,
reportproject.Table: reportproject.ValidColumn,
reportscorecard.Table: reportscorecard.ValidColumn,
reportscorecardcheck.Table: reportscorecardcheck.ValidColumn,
reportslsaprovenance.Table: reportslsaprovenance.ValidColumn,
reportvulnerability.Table: reportvulnerability.ValidColumn,
})
})
return columnCheck(table, column)

View File

@ -33,6 +33,138 @@ func (f DepsUsageEvidenceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.DepsUsageEvidenceMutation", m)
}
// The ReportDependencyFunc type is an adapter to allow the use of ordinary
// function as ReportDependency mutator.
type ReportDependencyFunc func(context.Context, *ent.ReportDependencyMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportDependencyFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportDependencyMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportDependencyMutation", m)
}
// The ReportDependencyGraphFunc type is an adapter to allow the use of ordinary
// function as ReportDependencyGraph mutator.
type ReportDependencyGraphFunc func(context.Context, *ent.ReportDependencyGraphMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportDependencyGraphFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportDependencyGraphMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportDependencyGraphMutation", m)
}
// The ReportLicenseFunc type is an adapter to allow the use of ordinary
// function as ReportLicense mutator.
type ReportLicenseFunc func(context.Context, *ent.ReportLicenseMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportLicenseFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportLicenseMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportLicenseMutation", m)
}
// The ReportMalwareFunc type is an adapter to allow the use of ordinary
// function as ReportMalware mutator.
type ReportMalwareFunc func(context.Context, *ent.ReportMalwareMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportMalwareFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportMalwareMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportMalwareMutation", m)
}
// The ReportPackageFunc type is an adapter to allow the use of ordinary
// function as ReportPackage mutator.
type ReportPackageFunc func(context.Context, *ent.ReportPackageMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportPackageFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportPackageMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportPackageMutation", m)
}
// The ReportPackageManifestFunc type is an adapter to allow the use of ordinary
// function as ReportPackageManifest mutator.
type ReportPackageManifestFunc func(context.Context, *ent.ReportPackageManifestMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportPackageManifestFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportPackageManifestMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportPackageManifestMutation", m)
}
// The ReportProjectFunc type is an adapter to allow the use of ordinary
// function as ReportProject mutator.
type ReportProjectFunc func(context.Context, *ent.ReportProjectMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportProjectFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportProjectMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportProjectMutation", m)
}
// The ReportScorecardFunc type is an adapter to allow the use of ordinary
// function as ReportScorecard mutator.
type ReportScorecardFunc func(context.Context, *ent.ReportScorecardMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportScorecardFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportScorecardMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportScorecardMutation", m)
}
// The ReportScorecardCheckFunc type is an adapter to allow the use of ordinary
// function as ReportScorecardCheck mutator.
type ReportScorecardCheckFunc func(context.Context, *ent.ReportScorecardCheckMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportScorecardCheckFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportScorecardCheckMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportScorecardCheckMutation", m)
}
// The ReportSlsaProvenanceFunc type is an adapter to allow the use of ordinary
// function as ReportSlsaProvenance mutator.
type ReportSlsaProvenanceFunc func(context.Context, *ent.ReportSlsaProvenanceMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportSlsaProvenanceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportSlsaProvenanceMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportSlsaProvenanceMutation", m)
}
// The ReportVulnerabilityFunc type is an adapter to allow the use of ordinary
// function as ReportVulnerability mutator.
type ReportVulnerabilityFunc func(context.Context, *ent.ReportVulnerabilityMutation) (ent.Value, error)
// Mutate calls f(ctx, m).
func (f ReportVulnerabilityFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
if mv, ok := m.(*ent.ReportVulnerabilityMutation); ok {
return f(ctx, mv)
}
return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.ReportVulnerabilityMutation", m)
}
// Condition is a hook condition function.
type Condition func(context.Context, ent.Mutation) bool

View File

@ -46,13 +46,379 @@ var (
},
},
}
// ReportDependenciesColumns holds the columns for the "report_dependencies" table.
ReportDependenciesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "dependency_package_id", Type: field.TypeString},
{Name: "dependency_name", Type: field.TypeString},
{Name: "dependency_version", Type: field.TypeString},
{Name: "dependency_ecosystem", Type: field.TypeString},
{Name: "dependency_type", Type: field.TypeString, Nullable: true},
{Name: "depth", Type: field.TypeInt, Default: 0},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_dependencies", Type: field.TypeInt, Nullable: true},
}
// ReportDependenciesTable holds the schema information for the "report_dependencies" table.
ReportDependenciesTable = &schema.Table{
Name: "report_dependencies",
Columns: ReportDependenciesColumns,
PrimaryKey: []*schema.Column{ReportDependenciesColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_dependencies_report_packages_dependencies",
Columns: []*schema.Column{ReportDependenciesColumns[9]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportDependencyGraphsColumns holds the columns for the "report_dependency_graphs" table.
ReportDependencyGraphsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "from_package_id", Type: field.TypeString},
{Name: "from_package_name", Type: field.TypeString},
{Name: "from_package_version", Type: field.TypeString},
{Name: "from_package_ecosystem", Type: field.TypeString},
{Name: "to_package_id", Type: field.TypeString},
{Name: "to_package_name", Type: field.TypeString},
{Name: "to_package_version", Type: field.TypeString},
{Name: "to_package_ecosystem", Type: field.TypeString},
{Name: "dependency_type", Type: field.TypeString, Nullable: true},
{Name: "version_constraint", Type: field.TypeString, Nullable: true},
{Name: "depth", Type: field.TypeInt, Default: 0},
{Name: "is_direct", Type: field.TypeBool, Default: false},
{Name: "is_root_edge", Type: field.TypeBool, Default: false},
{Name: "manifest_id", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
}
// ReportDependencyGraphsTable holds the schema information for the "report_dependency_graphs" table.
ReportDependencyGraphsTable = &schema.Table{
Name: "report_dependency_graphs",
Columns: ReportDependencyGraphsColumns,
PrimaryKey: []*schema.Column{ReportDependencyGraphsColumns[0]},
Indexes: []*schema.Index{
{
Name: "reportdependencygraph_from_package_id",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[1]},
},
{
Name: "reportdependencygraph_to_package_id",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[5]},
},
{
Name: "reportdependencygraph_manifest_id",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[14]},
},
{
Name: "reportdependencygraph_from_package_id_is_direct",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[1], ReportDependencyGraphsColumns[12]},
},
{
Name: "reportdependencygraph_is_root_edge",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[13]},
},
{
Name: "reportdependencygraph_from_package_id_to_package_id_manifest_id",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[1], ReportDependencyGraphsColumns[5], ReportDependencyGraphsColumns[14]},
},
{
Name: "reportdependencygraph_dependency_type",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[9]},
},
{
Name: "reportdependencygraph_depth",
Unique: false,
Columns: []*schema.Column{ReportDependencyGraphsColumns[11]},
},
},
}
// ReportLicensesColumns holds the columns for the "report_licenses" table.
ReportLicensesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "license_id", Type: field.TypeString},
{Name: "name", Type: field.TypeString, Nullable: true},
{Name: "spdx_id", Type: field.TypeString, Nullable: true},
{Name: "url", Type: field.TypeString, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_licenses", Type: field.TypeInt, Nullable: true},
}
// ReportLicensesTable holds the schema information for the "report_licenses" table.
ReportLicensesTable = &schema.Table{
Name: "report_licenses",
Columns: ReportLicensesColumns,
PrimaryKey: []*schema.Column{ReportLicensesColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_licenses_report_packages_licenses",
Columns: []*schema.Column{ReportLicensesColumns[7]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportMalwaresColumns holds the columns for the "report_malwares" table.
ReportMalwaresColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "analysis_id", Type: field.TypeString},
{Name: "is_malware", Type: field.TypeBool, Default: false},
{Name: "is_suspicious", Type: field.TypeBool, Default: false},
{Name: "confidence", Type: field.TypeString, Nullable: true},
{Name: "report", Type: field.TypeJSON, Nullable: true},
{Name: "verification_record", Type: field.TypeJSON, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_malware_analysis", Type: field.TypeInt, Unique: true, Nullable: true},
}
// ReportMalwaresTable holds the schema information for the "report_malwares" table.
ReportMalwaresTable = &schema.Table{
Name: "report_malwares",
Columns: ReportMalwaresColumns,
PrimaryKey: []*schema.Column{ReportMalwaresColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_malwares_report_packages_malware_analysis",
Columns: []*schema.Column{ReportMalwaresColumns[9]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportPackagesColumns holds the columns for the "report_packages" table.
ReportPackagesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "package_id", Type: field.TypeString, Unique: true},
{Name: "name", Type: field.TypeString},
{Name: "version", Type: field.TypeString},
{Name: "ecosystem", Type: field.TypeString},
{Name: "package_url", Type: field.TypeString},
{Name: "depth", Type: field.TypeInt, Default: 0},
{Name: "is_direct", Type: field.TypeBool, Default: false},
{Name: "is_malware", Type: field.TypeBool, Default: false},
{Name: "is_suspicious", Type: field.TypeBool, Default: false},
{Name: "package_details", Type: field.TypeJSON, Nullable: true},
{Name: "insights_v2", Type: field.TypeJSON, Nullable: true},
{Name: "code_analysis", Type: field.TypeJSON, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
}
// ReportPackagesTable holds the schema information for the "report_packages" table.
ReportPackagesTable = &schema.Table{
Name: "report_packages",
Columns: ReportPackagesColumns,
PrimaryKey: []*schema.Column{ReportPackagesColumns[0]},
}
// ReportPackageManifestsColumns holds the columns for the "report_package_manifests" table.
ReportPackageManifestsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "manifest_id", Type: field.TypeString, Unique: true},
{Name: "source_type", Type: field.TypeString},
{Name: "namespace", Type: field.TypeString},
{Name: "path", Type: field.TypeString},
{Name: "display_path", Type: field.TypeString},
{Name: "ecosystem", Type: field.TypeString},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
}
// ReportPackageManifestsTable holds the schema information for the "report_package_manifests" table.
ReportPackageManifestsTable = &schema.Table{
Name: "report_package_manifests",
Columns: ReportPackageManifestsColumns,
PrimaryKey: []*schema.Column{ReportPackageManifestsColumns[0]},
}
// ReportProjectsColumns holds the columns for the "report_projects" table.
ReportProjectsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "name", Type: field.TypeString},
{Name: "url", Type: field.TypeString, Nullable: true},
{Name: "description", Type: field.TypeString, Nullable: true},
{Name: "stars", Type: field.TypeInt32, Nullable: true},
{Name: "forks", Type: field.TypeInt32, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_projects", Type: field.TypeInt, Nullable: true},
}
// ReportProjectsTable holds the schema information for the "report_projects" table.
ReportProjectsTable = &schema.Table{
Name: "report_projects",
Columns: ReportProjectsColumns,
PrimaryKey: []*schema.Column{ReportProjectsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_projects_report_packages_projects",
Columns: []*schema.Column{ReportProjectsColumns[8]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportScorecardsColumns holds the columns for the "report_scorecards" table.
ReportScorecardsColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "score", Type: field.TypeFloat32},
{Name: "scorecard_version", Type: field.TypeString},
{Name: "repo_name", Type: field.TypeString},
{Name: "repo_commit", Type: field.TypeString},
{Name: "date", Type: field.TypeString, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_project_scorecard", Type: field.TypeInt, Unique: true, Nullable: true},
}
// ReportScorecardsTable holds the schema information for the "report_scorecards" table.
ReportScorecardsTable = &schema.Table{
Name: "report_scorecards",
Columns: ReportScorecardsColumns,
PrimaryKey: []*schema.Column{ReportScorecardsColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_scorecards_report_projects_scorecard",
Columns: []*schema.Column{ReportScorecardsColumns[8]},
RefColumns: []*schema.Column{ReportProjectsColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportScorecardChecksColumns holds the columns for the "report_scorecard_checks" table.
ReportScorecardChecksColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "name", Type: field.TypeString},
{Name: "score", Type: field.TypeFloat32},
{Name: "reason", Type: field.TypeString, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_scorecard_checks", Type: field.TypeInt, Nullable: true},
}
// ReportScorecardChecksTable holds the schema information for the "report_scorecard_checks" table.
ReportScorecardChecksTable = &schema.Table{
Name: "report_scorecard_checks",
Columns: ReportScorecardChecksColumns,
PrimaryKey: []*schema.Column{ReportScorecardChecksColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_scorecard_checks_report_scorecards_checks",
Columns: []*schema.Column{ReportScorecardChecksColumns[6]},
RefColumns: []*schema.Column{ReportScorecardsColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportSlsaProvenancesColumns holds the columns for the "report_slsa_provenances" table.
ReportSlsaProvenancesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "source_repository", Type: field.TypeString},
{Name: "commit_sha", Type: field.TypeString},
{Name: "url", Type: field.TypeString},
{Name: "verified", Type: field.TypeBool, Default: false},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_slsa_provenances", Type: field.TypeInt, Nullable: true},
}
// ReportSlsaProvenancesTable holds the schema information for the "report_slsa_provenances" table.
ReportSlsaProvenancesTable = &schema.Table{
Name: "report_slsa_provenances",
Columns: ReportSlsaProvenancesColumns,
PrimaryKey: []*schema.Column{ReportSlsaProvenancesColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_slsa_provenances_report_packages_slsa_provenances",
Columns: []*schema.Column{ReportSlsaProvenancesColumns[7]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportVulnerabilitiesColumns holds the columns for the "report_vulnerabilities" table.
ReportVulnerabilitiesColumns = []*schema.Column{
{Name: "id", Type: field.TypeInt, Increment: true},
{Name: "vulnerability_id", Type: field.TypeString},
{Name: "title", Type: field.TypeString},
{Name: "description", Type: field.TypeString, Nullable: true},
{Name: "aliases", Type: field.TypeJSON, Nullable: true},
{Name: "severity", Type: field.TypeString, Nullable: true},
{Name: "severity_type", Type: field.TypeString, Nullable: true},
{Name: "cvss_score", Type: field.TypeFloat64, Nullable: true},
{Name: "severity_details", Type: field.TypeJSON, Nullable: true},
{Name: "created_at", Type: field.TypeTime, Nullable: true},
{Name: "updated_at", Type: field.TypeTime, Nullable: true},
{Name: "report_package_vulnerabilities", Type: field.TypeInt, Nullable: true},
}
// ReportVulnerabilitiesTable holds the schema information for the "report_vulnerabilities" table.
ReportVulnerabilitiesTable = &schema.Table{
Name: "report_vulnerabilities",
Columns: ReportVulnerabilitiesColumns,
PrimaryKey: []*schema.Column{ReportVulnerabilitiesColumns[0]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_vulnerabilities_report_packages_vulnerabilities",
Columns: []*schema.Column{ReportVulnerabilitiesColumns[11]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// ReportPackageManifestPackagesColumns holds the columns for the "report_package_manifest_packages" table.
ReportPackageManifestPackagesColumns = []*schema.Column{
{Name: "report_package_manifest_id", Type: field.TypeInt},
{Name: "report_package_id", Type: field.TypeInt},
}
// ReportPackageManifestPackagesTable holds the schema information for the "report_package_manifest_packages" table.
ReportPackageManifestPackagesTable = &schema.Table{
Name: "report_package_manifest_packages",
Columns: ReportPackageManifestPackagesColumns,
PrimaryKey: []*schema.Column{ReportPackageManifestPackagesColumns[0], ReportPackageManifestPackagesColumns[1]},
ForeignKeys: []*schema.ForeignKey{
{
Symbol: "report_package_manifest_packages_report_package_manifest_id",
Columns: []*schema.Column{ReportPackageManifestPackagesColumns[0]},
RefColumns: []*schema.Column{ReportPackageManifestsColumns[0]},
OnDelete: schema.Cascade,
},
{
Symbol: "report_package_manifest_packages_report_package_id",
Columns: []*schema.Column{ReportPackageManifestPackagesColumns[1]},
RefColumns: []*schema.Column{ReportPackagesColumns[0]},
OnDelete: schema.Cascade,
},
},
}
// Tables holds all the tables in the schema.
Tables = []*schema.Table{
CodeSourceFilesTable,
DepsUsageEvidencesTable,
ReportDependenciesTable,
ReportDependencyGraphsTable,
ReportLicensesTable,
ReportMalwaresTable,
ReportPackagesTable,
ReportPackageManifestsTable,
ReportProjectsTable,
ReportScorecardsTable,
ReportScorecardChecksTable,
ReportSlsaProvenancesTable,
ReportVulnerabilitiesTable,
ReportPackageManifestPackagesTable,
}
)
func init() {
DepsUsageEvidencesTable.ForeignKeys[0].RefTable = CodeSourceFilesTable
ReportDependenciesTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportLicensesTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportMalwaresTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportProjectsTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportScorecardsTable.ForeignKeys[0].RefTable = ReportProjectsTable
ReportScorecardChecksTable.ForeignKeys[0].RefTable = ReportScorecardsTable
ReportSlsaProvenancesTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportVulnerabilitiesTable.ForeignKeys[0].RefTable = ReportPackagesTable
ReportPackageManifestPackagesTable.ForeignKeys[0].RefTable = ReportPackageManifestsTable
ReportPackageManifestPackagesTable.ForeignKeys[1].RefTable = ReportPackagesTable
}

File diff suppressed because it is too large Load Diff

View File

@ -11,3 +11,36 @@ type CodeSourceFile func(*sql.Selector)
// DepsUsageEvidence is the predicate function for depsusageevidence builders.
type DepsUsageEvidence func(*sql.Selector)
// ReportDependency is the predicate function for reportdependency builders.
type ReportDependency func(*sql.Selector)
// ReportDependencyGraph is the predicate function for reportdependencygraph builders.
type ReportDependencyGraph func(*sql.Selector)
// ReportLicense is the predicate function for reportlicense builders.
type ReportLicense func(*sql.Selector)
// ReportMalware is the predicate function for reportmalware builders.
type ReportMalware func(*sql.Selector)
// ReportPackage is the predicate function for reportpackage builders.
type ReportPackage func(*sql.Selector)
// ReportPackageManifest is the predicate function for reportpackagemanifest builders.
type ReportPackageManifest func(*sql.Selector)
// ReportProject is the predicate function for reportproject builders.
type ReportProject func(*sql.Selector)
// ReportScorecard is the predicate function for reportscorecard builders.
type ReportScorecard func(*sql.Selector)
// ReportScorecardCheck is the predicate function for reportscorecardcheck builders.
type ReportScorecardCheck func(*sql.Selector)
// ReportSlsaProvenance is the predicate function for reportslsaprovenance builders.
type ReportSlsaProvenance func(*sql.Selector)
// ReportVulnerability is the predicate function for reportvulnerability builders.
type ReportVulnerability func(*sql.Selector)

222
ent/reportdependency.go Normal file
View File

@ -0,0 +1,222 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/safedep/vet/ent/reportdependency"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportDependency is the model entity for the ReportDependency schema.
type ReportDependency struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// DependencyPackageID holds the value of the "dependency_package_id" field.
DependencyPackageID string `json:"dependency_package_id,omitempty"`
// DependencyName holds the value of the "dependency_name" field.
DependencyName string `json:"dependency_name,omitempty"`
// DependencyVersion holds the value of the "dependency_version" field.
DependencyVersion string `json:"dependency_version,omitempty"`
// DependencyEcosystem holds the value of the "dependency_ecosystem" field.
DependencyEcosystem string `json:"dependency_ecosystem,omitempty"`
// DependencyType holds the value of the "dependency_type" field.
DependencyType string `json:"dependency_type,omitempty"`
// Depth holds the value of the "depth" field.
Depth int `json:"depth,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the ReportDependencyQuery when eager-loading is set.
Edges ReportDependencyEdges `json:"edges"`
report_package_dependencies *int
selectValues sql.SelectValues
}
// ReportDependencyEdges holds the relations/edges for other nodes in the graph.
type ReportDependencyEdges struct {
// Package holds the value of the package edge.
Package *ReportPackage `json:"package,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// PackageOrErr returns the Package value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ReportDependencyEdges) PackageOrErr() (*ReportPackage, error) {
if e.Package != nil {
return e.Package, nil
} else if e.loadedTypes[0] {
return nil, &NotFoundError{label: reportpackage.Label}
}
return nil, &NotLoadedError{edge: "package"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*ReportDependency) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case reportdependency.FieldID, reportdependency.FieldDepth:
values[i] = new(sql.NullInt64)
case reportdependency.FieldDependencyPackageID, reportdependency.FieldDependencyName, reportdependency.FieldDependencyVersion, reportdependency.FieldDependencyEcosystem, reportdependency.FieldDependencyType:
values[i] = new(sql.NullString)
case reportdependency.FieldCreatedAt, reportdependency.FieldUpdatedAt:
values[i] = new(sql.NullTime)
case reportdependency.ForeignKeys[0]: // report_package_dependencies
values[i] = new(sql.NullInt64)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the ReportDependency fields.
func (rd *ReportDependency) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case reportdependency.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
rd.ID = int(value.Int64)
case reportdependency.FieldDependencyPackageID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_package_id", values[i])
} else if value.Valid {
rd.DependencyPackageID = value.String
}
case reportdependency.FieldDependencyName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_name", values[i])
} else if value.Valid {
rd.DependencyName = value.String
}
case reportdependency.FieldDependencyVersion:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_version", values[i])
} else if value.Valid {
rd.DependencyVersion = value.String
}
case reportdependency.FieldDependencyEcosystem:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_ecosystem", values[i])
} else if value.Valid {
rd.DependencyEcosystem = value.String
}
case reportdependency.FieldDependencyType:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_type", values[i])
} else if value.Valid {
rd.DependencyType = value.String
}
case reportdependency.FieldDepth:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for field depth", values[i])
} else if value.Valid {
rd.Depth = int(value.Int64)
}
case reportdependency.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
rd.CreatedAt = value.Time
}
case reportdependency.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
rd.UpdatedAt = value.Time
}
case reportdependency.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field report_package_dependencies", value)
} else if value.Valid {
rd.report_package_dependencies = new(int)
*rd.report_package_dependencies = int(value.Int64)
}
default:
rd.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the ReportDependency.
// This includes values selected through modifiers, order, etc.
func (rd *ReportDependency) Value(name string) (ent.Value, error) {
return rd.selectValues.Get(name)
}
// QueryPackage queries the "package" edge of the ReportDependency entity.
func (rd *ReportDependency) QueryPackage() *ReportPackageQuery {
return NewReportDependencyClient(rd.config).QueryPackage(rd)
}
// Update returns a builder for updating this ReportDependency.
// Note that you need to call ReportDependency.Unwrap() before calling this method if this ReportDependency
// was returned from a transaction, and the transaction was committed or rolled back.
func (rd *ReportDependency) Update() *ReportDependencyUpdateOne {
return NewReportDependencyClient(rd.config).UpdateOne(rd)
}
// Unwrap unwraps the ReportDependency entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (rd *ReportDependency) Unwrap() *ReportDependency {
_tx, ok := rd.config.driver.(*txDriver)
if !ok {
panic("ent: ReportDependency is not a transactional entity")
}
rd.config.driver = _tx.drv
return rd
}
// String implements the fmt.Stringer.
func (rd *ReportDependency) String() string {
var builder strings.Builder
builder.WriteString("ReportDependency(")
builder.WriteString(fmt.Sprintf("id=%v, ", rd.ID))
builder.WriteString("dependency_package_id=")
builder.WriteString(rd.DependencyPackageID)
builder.WriteString(", ")
builder.WriteString("dependency_name=")
builder.WriteString(rd.DependencyName)
builder.WriteString(", ")
builder.WriteString("dependency_version=")
builder.WriteString(rd.DependencyVersion)
builder.WriteString(", ")
builder.WriteString("dependency_ecosystem=")
builder.WriteString(rd.DependencyEcosystem)
builder.WriteString(", ")
builder.WriteString("dependency_type=")
builder.WriteString(rd.DependencyType)
builder.WriteString(", ")
builder.WriteString("depth=")
builder.WriteString(fmt.Sprintf("%v", rd.Depth))
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(rd.CreatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(rd.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// ReportDependencies is a parsable slice of ReportDependency.
type ReportDependencies []*ReportDependency

View File

@ -0,0 +1,151 @@
// Code generated by ent, DO NOT EDIT.
package reportdependency
import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
const (
// Label holds the string label denoting the reportdependency type in the database.
Label = "report_dependency"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldDependencyPackageID holds the string denoting the dependency_package_id field in the database.
FieldDependencyPackageID = "dependency_package_id"
// FieldDependencyName holds the string denoting the dependency_name field in the database.
FieldDependencyName = "dependency_name"
// FieldDependencyVersion holds the string denoting the dependency_version field in the database.
FieldDependencyVersion = "dependency_version"
// FieldDependencyEcosystem holds the string denoting the dependency_ecosystem field in the database.
FieldDependencyEcosystem = "dependency_ecosystem"
// FieldDependencyType holds the string denoting the dependency_type field in the database.
FieldDependencyType = "dependency_type"
// FieldDepth holds the string denoting the depth field in the database.
FieldDepth = "depth"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgePackage holds the string denoting the package edge name in mutations.
EdgePackage = "package"
// Table holds the table name of the reportdependency in the database.
Table = "report_dependencies"
// PackageTable is the table that holds the package relation/edge.
PackageTable = "report_dependencies"
// PackageInverseTable is the table name for the ReportPackage entity.
// It exists in this package in order to avoid circular dependency with the "reportpackage" package.
PackageInverseTable = "report_packages"
// PackageColumn is the table column denoting the package relation/edge.
PackageColumn = "report_package_dependencies"
)
// Columns holds all SQL columns for reportdependency fields.
var Columns = []string{
FieldID,
FieldDependencyPackageID,
FieldDependencyName,
FieldDependencyVersion,
FieldDependencyEcosystem,
FieldDependencyType,
FieldDepth,
FieldCreatedAt,
FieldUpdatedAt,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "report_dependencies"
// table and are not defined as standalone fields in the schema.
var ForeignKeys = []string{
"report_package_dependencies",
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
for i := range ForeignKeys {
if column == ForeignKeys[i] {
return true
}
}
return false
}
var (
// DependencyPackageIDValidator is a validator for the "dependency_package_id" field. It is called by the builders before save.
DependencyPackageIDValidator func(string) error
// DependencyNameValidator is a validator for the "dependency_name" field. It is called by the builders before save.
DependencyNameValidator func(string) error
// DependencyVersionValidator is a validator for the "dependency_version" field. It is called by the builders before save.
DependencyVersionValidator func(string) error
// DependencyEcosystemValidator is a validator for the "dependency_ecosystem" field. It is called by the builders before save.
DependencyEcosystemValidator func(string) error
// DefaultDepth holds the default value on creation for the "depth" field.
DefaultDepth int
)
// OrderOption defines the ordering options for the ReportDependency queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByDependencyPackageID orders the results by the dependency_package_id field.
func ByDependencyPackageID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyPackageID, opts...).ToFunc()
}
// ByDependencyName orders the results by the dependency_name field.
func ByDependencyName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyName, opts...).ToFunc()
}
// ByDependencyVersion orders the results by the dependency_version field.
func ByDependencyVersion(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyVersion, opts...).ToFunc()
}
// ByDependencyEcosystem orders the results by the dependency_ecosystem field.
func ByDependencyEcosystem(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyEcosystem, opts...).ToFunc()
}
// ByDependencyType orders the results by the dependency_type field.
func ByDependencyType(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyType, opts...).ToFunc()
}
// ByDepth orders the results by the depth field.
func ByDepth(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDepth, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByPackageField orders the results by package field.
func ByPackageField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newPackageStep(), sql.OrderByField(field, opts...))
}
}
func newPackageStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PackageInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PackageTable, PackageColumn),
)
}

View File

@ -0,0 +1,609 @@
// Code generated by ent, DO NOT EDIT.
package reportdependency
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/safedep/vet/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldID, id))
}
// DependencyPackageID applies equality check predicate on the "dependency_package_id" field. It's identical to DependencyPackageIDEQ.
func DependencyPackageID(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyPackageID, v))
}
// DependencyName applies equality check predicate on the "dependency_name" field. It's identical to DependencyNameEQ.
func DependencyName(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyName, v))
}
// DependencyVersion applies equality check predicate on the "dependency_version" field. It's identical to DependencyVersionEQ.
func DependencyVersion(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyVersion, v))
}
// DependencyEcosystem applies equality check predicate on the "dependency_ecosystem" field. It's identical to DependencyEcosystemEQ.
func DependencyEcosystem(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyEcosystem, v))
}
// DependencyType applies equality check predicate on the "dependency_type" field. It's identical to DependencyTypeEQ.
func DependencyType(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyType, v))
}
// Depth applies equality check predicate on the "depth" field. It's identical to DepthEQ.
func Depth(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDepth, v))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldUpdatedAt, v))
}
// DependencyPackageIDEQ applies the EQ predicate on the "dependency_package_id" field.
func DependencyPackageIDEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyPackageID, v))
}
// DependencyPackageIDNEQ applies the NEQ predicate on the "dependency_package_id" field.
func DependencyPackageIDNEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDependencyPackageID, v))
}
// DependencyPackageIDIn applies the In predicate on the "dependency_package_id" field.
func DependencyPackageIDIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDependencyPackageID, vs...))
}
// DependencyPackageIDNotIn applies the NotIn predicate on the "dependency_package_id" field.
func DependencyPackageIDNotIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDependencyPackageID, vs...))
}
// DependencyPackageIDGT applies the GT predicate on the "dependency_package_id" field.
func DependencyPackageIDGT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDependencyPackageID, v))
}
// DependencyPackageIDGTE applies the GTE predicate on the "dependency_package_id" field.
func DependencyPackageIDGTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDependencyPackageID, v))
}
// DependencyPackageIDLT applies the LT predicate on the "dependency_package_id" field.
func DependencyPackageIDLT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDependencyPackageID, v))
}
// DependencyPackageIDLTE applies the LTE predicate on the "dependency_package_id" field.
func DependencyPackageIDLTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDependencyPackageID, v))
}
// DependencyPackageIDContains applies the Contains predicate on the "dependency_package_id" field.
func DependencyPackageIDContains(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContains(FieldDependencyPackageID, v))
}
// DependencyPackageIDHasPrefix applies the HasPrefix predicate on the "dependency_package_id" field.
func DependencyPackageIDHasPrefix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasPrefix(FieldDependencyPackageID, v))
}
// DependencyPackageIDHasSuffix applies the HasSuffix predicate on the "dependency_package_id" field.
func DependencyPackageIDHasSuffix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasSuffix(FieldDependencyPackageID, v))
}
// DependencyPackageIDEqualFold applies the EqualFold predicate on the "dependency_package_id" field.
func DependencyPackageIDEqualFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEqualFold(FieldDependencyPackageID, v))
}
// DependencyPackageIDContainsFold applies the ContainsFold predicate on the "dependency_package_id" field.
func DependencyPackageIDContainsFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContainsFold(FieldDependencyPackageID, v))
}
// DependencyNameEQ applies the EQ predicate on the "dependency_name" field.
func DependencyNameEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyName, v))
}
// DependencyNameNEQ applies the NEQ predicate on the "dependency_name" field.
func DependencyNameNEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDependencyName, v))
}
// DependencyNameIn applies the In predicate on the "dependency_name" field.
func DependencyNameIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDependencyName, vs...))
}
// DependencyNameNotIn applies the NotIn predicate on the "dependency_name" field.
func DependencyNameNotIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDependencyName, vs...))
}
// DependencyNameGT applies the GT predicate on the "dependency_name" field.
func DependencyNameGT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDependencyName, v))
}
// DependencyNameGTE applies the GTE predicate on the "dependency_name" field.
func DependencyNameGTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDependencyName, v))
}
// DependencyNameLT applies the LT predicate on the "dependency_name" field.
func DependencyNameLT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDependencyName, v))
}
// DependencyNameLTE applies the LTE predicate on the "dependency_name" field.
func DependencyNameLTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDependencyName, v))
}
// DependencyNameContains applies the Contains predicate on the "dependency_name" field.
func DependencyNameContains(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContains(FieldDependencyName, v))
}
// DependencyNameHasPrefix applies the HasPrefix predicate on the "dependency_name" field.
func DependencyNameHasPrefix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasPrefix(FieldDependencyName, v))
}
// DependencyNameHasSuffix applies the HasSuffix predicate on the "dependency_name" field.
func DependencyNameHasSuffix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasSuffix(FieldDependencyName, v))
}
// DependencyNameEqualFold applies the EqualFold predicate on the "dependency_name" field.
func DependencyNameEqualFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEqualFold(FieldDependencyName, v))
}
// DependencyNameContainsFold applies the ContainsFold predicate on the "dependency_name" field.
func DependencyNameContainsFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContainsFold(FieldDependencyName, v))
}
// DependencyVersionEQ applies the EQ predicate on the "dependency_version" field.
func DependencyVersionEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyVersion, v))
}
// DependencyVersionNEQ applies the NEQ predicate on the "dependency_version" field.
func DependencyVersionNEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDependencyVersion, v))
}
// DependencyVersionIn applies the In predicate on the "dependency_version" field.
func DependencyVersionIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDependencyVersion, vs...))
}
// DependencyVersionNotIn applies the NotIn predicate on the "dependency_version" field.
func DependencyVersionNotIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDependencyVersion, vs...))
}
// DependencyVersionGT applies the GT predicate on the "dependency_version" field.
func DependencyVersionGT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDependencyVersion, v))
}
// DependencyVersionGTE applies the GTE predicate on the "dependency_version" field.
func DependencyVersionGTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDependencyVersion, v))
}
// DependencyVersionLT applies the LT predicate on the "dependency_version" field.
func DependencyVersionLT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDependencyVersion, v))
}
// DependencyVersionLTE applies the LTE predicate on the "dependency_version" field.
func DependencyVersionLTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDependencyVersion, v))
}
// DependencyVersionContains applies the Contains predicate on the "dependency_version" field.
func DependencyVersionContains(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContains(FieldDependencyVersion, v))
}
// DependencyVersionHasPrefix applies the HasPrefix predicate on the "dependency_version" field.
func DependencyVersionHasPrefix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasPrefix(FieldDependencyVersion, v))
}
// DependencyVersionHasSuffix applies the HasSuffix predicate on the "dependency_version" field.
func DependencyVersionHasSuffix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasSuffix(FieldDependencyVersion, v))
}
// DependencyVersionEqualFold applies the EqualFold predicate on the "dependency_version" field.
func DependencyVersionEqualFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEqualFold(FieldDependencyVersion, v))
}
// DependencyVersionContainsFold applies the ContainsFold predicate on the "dependency_version" field.
func DependencyVersionContainsFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContainsFold(FieldDependencyVersion, v))
}
// DependencyEcosystemEQ applies the EQ predicate on the "dependency_ecosystem" field.
func DependencyEcosystemEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyEcosystem, v))
}
// DependencyEcosystemNEQ applies the NEQ predicate on the "dependency_ecosystem" field.
func DependencyEcosystemNEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDependencyEcosystem, v))
}
// DependencyEcosystemIn applies the In predicate on the "dependency_ecosystem" field.
func DependencyEcosystemIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDependencyEcosystem, vs...))
}
// DependencyEcosystemNotIn applies the NotIn predicate on the "dependency_ecosystem" field.
func DependencyEcosystemNotIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDependencyEcosystem, vs...))
}
// DependencyEcosystemGT applies the GT predicate on the "dependency_ecosystem" field.
func DependencyEcosystemGT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDependencyEcosystem, v))
}
// DependencyEcosystemGTE applies the GTE predicate on the "dependency_ecosystem" field.
func DependencyEcosystemGTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDependencyEcosystem, v))
}
// DependencyEcosystemLT applies the LT predicate on the "dependency_ecosystem" field.
func DependencyEcosystemLT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDependencyEcosystem, v))
}
// DependencyEcosystemLTE applies the LTE predicate on the "dependency_ecosystem" field.
func DependencyEcosystemLTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDependencyEcosystem, v))
}
// DependencyEcosystemContains applies the Contains predicate on the "dependency_ecosystem" field.
func DependencyEcosystemContains(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContains(FieldDependencyEcosystem, v))
}
// DependencyEcosystemHasPrefix applies the HasPrefix predicate on the "dependency_ecosystem" field.
func DependencyEcosystemHasPrefix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasPrefix(FieldDependencyEcosystem, v))
}
// DependencyEcosystemHasSuffix applies the HasSuffix predicate on the "dependency_ecosystem" field.
func DependencyEcosystemHasSuffix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasSuffix(FieldDependencyEcosystem, v))
}
// DependencyEcosystemEqualFold applies the EqualFold predicate on the "dependency_ecosystem" field.
func DependencyEcosystemEqualFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEqualFold(FieldDependencyEcosystem, v))
}
// DependencyEcosystemContainsFold applies the ContainsFold predicate on the "dependency_ecosystem" field.
func DependencyEcosystemContainsFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContainsFold(FieldDependencyEcosystem, v))
}
// DependencyTypeEQ applies the EQ predicate on the "dependency_type" field.
func DependencyTypeEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDependencyType, v))
}
// DependencyTypeNEQ applies the NEQ predicate on the "dependency_type" field.
func DependencyTypeNEQ(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDependencyType, v))
}
// DependencyTypeIn applies the In predicate on the "dependency_type" field.
func DependencyTypeIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDependencyType, vs...))
}
// DependencyTypeNotIn applies the NotIn predicate on the "dependency_type" field.
func DependencyTypeNotIn(vs ...string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDependencyType, vs...))
}
// DependencyTypeGT applies the GT predicate on the "dependency_type" field.
func DependencyTypeGT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDependencyType, v))
}
// DependencyTypeGTE applies the GTE predicate on the "dependency_type" field.
func DependencyTypeGTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDependencyType, v))
}
// DependencyTypeLT applies the LT predicate on the "dependency_type" field.
func DependencyTypeLT(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDependencyType, v))
}
// DependencyTypeLTE applies the LTE predicate on the "dependency_type" field.
func DependencyTypeLTE(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDependencyType, v))
}
// DependencyTypeContains applies the Contains predicate on the "dependency_type" field.
func DependencyTypeContains(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContains(FieldDependencyType, v))
}
// DependencyTypeHasPrefix applies the HasPrefix predicate on the "dependency_type" field.
func DependencyTypeHasPrefix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasPrefix(FieldDependencyType, v))
}
// DependencyTypeHasSuffix applies the HasSuffix predicate on the "dependency_type" field.
func DependencyTypeHasSuffix(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldHasSuffix(FieldDependencyType, v))
}
// DependencyTypeIsNil applies the IsNil predicate on the "dependency_type" field.
func DependencyTypeIsNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIsNull(FieldDependencyType))
}
// DependencyTypeNotNil applies the NotNil predicate on the "dependency_type" field.
func DependencyTypeNotNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotNull(FieldDependencyType))
}
// DependencyTypeEqualFold applies the EqualFold predicate on the "dependency_type" field.
func DependencyTypeEqualFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEqualFold(FieldDependencyType, v))
}
// DependencyTypeContainsFold applies the ContainsFold predicate on the "dependency_type" field.
func DependencyTypeContainsFold(v string) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldContainsFold(FieldDependencyType, v))
}
// DepthEQ applies the EQ predicate on the "depth" field.
func DepthEQ(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldDepth, v))
}
// DepthNEQ applies the NEQ predicate on the "depth" field.
func DepthNEQ(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldDepth, v))
}
// DepthIn applies the In predicate on the "depth" field.
func DepthIn(vs ...int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldDepth, vs...))
}
// DepthNotIn applies the NotIn predicate on the "depth" field.
func DepthNotIn(vs ...int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldDepth, vs...))
}
// DepthGT applies the GT predicate on the "depth" field.
func DepthGT(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldDepth, v))
}
// DepthGTE applies the GTE predicate on the "depth" field.
func DepthGTE(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldDepth, v))
}
// DepthLT applies the LT predicate on the "depth" field.
func DepthLT(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldDepth, v))
}
// DepthLTE applies the LTE predicate on the "depth" field.
func DepthLTE(v int) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldDepth, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
func CreatedAtIsNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIsNull(FieldCreatedAt))
}
// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
func CreatedAtNotNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotNull(FieldCreatedAt))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
func UpdatedAtIsNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldIsNull(FieldUpdatedAt))
}
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
func UpdatedAtNotNil() predicate.ReportDependency {
return predicate.ReportDependency(sql.FieldNotNull(FieldUpdatedAt))
}
// HasPackage applies the HasEdge predicate on the "package" edge.
func HasPackage() predicate.ReportDependency {
return predicate.ReportDependency(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PackageTable, PackageColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasPackageWith applies the HasEdge predicate on the "package" edge with a given conditions (other predicates).
func HasPackageWith(preds ...predicate.ReportPackage) predicate.ReportDependency {
return predicate.ReportDependency(func(s *sql.Selector) {
step := newPackageStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.ReportDependency) predicate.ReportDependency {
return predicate.ReportDependency(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.ReportDependency) predicate.ReportDependency {
return predicate.ReportDependency(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.ReportDependency) predicate.ReportDependency {
return predicate.ReportDependency(sql.NotPredicates(p))
}

View File

@ -0,0 +1,365 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/reportdependency"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportDependencyCreate is the builder for creating a ReportDependency entity.
type ReportDependencyCreate struct {
config
mutation *ReportDependencyMutation
hooks []Hook
}
// SetDependencyPackageID sets the "dependency_package_id" field.
func (rdc *ReportDependencyCreate) SetDependencyPackageID(s string) *ReportDependencyCreate {
rdc.mutation.SetDependencyPackageID(s)
return rdc
}
// SetDependencyName sets the "dependency_name" field.
func (rdc *ReportDependencyCreate) SetDependencyName(s string) *ReportDependencyCreate {
rdc.mutation.SetDependencyName(s)
return rdc
}
// SetDependencyVersion sets the "dependency_version" field.
func (rdc *ReportDependencyCreate) SetDependencyVersion(s string) *ReportDependencyCreate {
rdc.mutation.SetDependencyVersion(s)
return rdc
}
// SetDependencyEcosystem sets the "dependency_ecosystem" field.
func (rdc *ReportDependencyCreate) SetDependencyEcosystem(s string) *ReportDependencyCreate {
rdc.mutation.SetDependencyEcosystem(s)
return rdc
}
// SetDependencyType sets the "dependency_type" field.
func (rdc *ReportDependencyCreate) SetDependencyType(s string) *ReportDependencyCreate {
rdc.mutation.SetDependencyType(s)
return rdc
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rdc *ReportDependencyCreate) SetNillableDependencyType(s *string) *ReportDependencyCreate {
if s != nil {
rdc.SetDependencyType(*s)
}
return rdc
}
// SetDepth sets the "depth" field.
func (rdc *ReportDependencyCreate) SetDepth(i int) *ReportDependencyCreate {
rdc.mutation.SetDepth(i)
return rdc
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rdc *ReportDependencyCreate) SetNillableDepth(i *int) *ReportDependencyCreate {
if i != nil {
rdc.SetDepth(*i)
}
return rdc
}
// SetCreatedAt sets the "created_at" field.
func (rdc *ReportDependencyCreate) SetCreatedAt(t time.Time) *ReportDependencyCreate {
rdc.mutation.SetCreatedAt(t)
return rdc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rdc *ReportDependencyCreate) SetNillableCreatedAt(t *time.Time) *ReportDependencyCreate {
if t != nil {
rdc.SetCreatedAt(*t)
}
return rdc
}
// SetUpdatedAt sets the "updated_at" field.
func (rdc *ReportDependencyCreate) SetUpdatedAt(t time.Time) *ReportDependencyCreate {
rdc.mutation.SetUpdatedAt(t)
return rdc
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rdc *ReportDependencyCreate) SetNillableUpdatedAt(t *time.Time) *ReportDependencyCreate {
if t != nil {
rdc.SetUpdatedAt(*t)
}
return rdc
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rdc *ReportDependencyCreate) SetPackageID(id int) *ReportDependencyCreate {
rdc.mutation.SetPackageID(id)
return rdc
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rdc *ReportDependencyCreate) SetNillablePackageID(id *int) *ReportDependencyCreate {
if id != nil {
rdc = rdc.SetPackageID(*id)
}
return rdc
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rdc *ReportDependencyCreate) SetPackage(r *ReportPackage) *ReportDependencyCreate {
return rdc.SetPackageID(r.ID)
}
// Mutation returns the ReportDependencyMutation object of the builder.
func (rdc *ReportDependencyCreate) Mutation() *ReportDependencyMutation {
return rdc.mutation
}
// Save creates the ReportDependency in the database.
func (rdc *ReportDependencyCreate) Save(ctx context.Context) (*ReportDependency, error) {
rdc.defaults()
return withHooks(ctx, rdc.sqlSave, rdc.mutation, rdc.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (rdc *ReportDependencyCreate) SaveX(ctx context.Context) *ReportDependency {
v, err := rdc.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rdc *ReportDependencyCreate) Exec(ctx context.Context) error {
_, err := rdc.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdc *ReportDependencyCreate) ExecX(ctx context.Context) {
if err := rdc.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (rdc *ReportDependencyCreate) defaults() {
if _, ok := rdc.mutation.Depth(); !ok {
v := reportdependency.DefaultDepth
rdc.mutation.SetDepth(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (rdc *ReportDependencyCreate) check() error {
if _, ok := rdc.mutation.DependencyPackageID(); !ok {
return &ValidationError{Name: "dependency_package_id", err: errors.New(`ent: missing required field "ReportDependency.dependency_package_id"`)}
}
if v, ok := rdc.mutation.DependencyPackageID(); ok {
if err := reportdependency.DependencyPackageIDValidator(v); err != nil {
return &ValidationError{Name: "dependency_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_package_id": %w`, err)}
}
}
if _, ok := rdc.mutation.DependencyName(); !ok {
return &ValidationError{Name: "dependency_name", err: errors.New(`ent: missing required field "ReportDependency.dependency_name"`)}
}
if v, ok := rdc.mutation.DependencyName(); ok {
if err := reportdependency.DependencyNameValidator(v); err != nil {
return &ValidationError{Name: "dependency_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_name": %w`, err)}
}
}
if _, ok := rdc.mutation.DependencyVersion(); !ok {
return &ValidationError{Name: "dependency_version", err: errors.New(`ent: missing required field "ReportDependency.dependency_version"`)}
}
if v, ok := rdc.mutation.DependencyVersion(); ok {
if err := reportdependency.DependencyVersionValidator(v); err != nil {
return &ValidationError{Name: "dependency_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_version": %w`, err)}
}
}
if _, ok := rdc.mutation.DependencyEcosystem(); !ok {
return &ValidationError{Name: "dependency_ecosystem", err: errors.New(`ent: missing required field "ReportDependency.dependency_ecosystem"`)}
}
if v, ok := rdc.mutation.DependencyEcosystem(); ok {
if err := reportdependency.DependencyEcosystemValidator(v); err != nil {
return &ValidationError{Name: "dependency_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_ecosystem": %w`, err)}
}
}
if _, ok := rdc.mutation.Depth(); !ok {
return &ValidationError{Name: "depth", err: errors.New(`ent: missing required field "ReportDependency.depth"`)}
}
return nil
}
func (rdc *ReportDependencyCreate) sqlSave(ctx context.Context) (*ReportDependency, error) {
if err := rdc.check(); err != nil {
return nil, err
}
_node, _spec := rdc.createSpec()
if err := sqlgraph.CreateNode(ctx, rdc.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
rdc.mutation.id = &_node.ID
rdc.mutation.done = true
return _node, nil
}
func (rdc *ReportDependencyCreate) createSpec() (*ReportDependency, *sqlgraph.CreateSpec) {
var (
_node = &ReportDependency{config: rdc.config}
_spec = sqlgraph.NewCreateSpec(reportdependency.Table, sqlgraph.NewFieldSpec(reportdependency.FieldID, field.TypeInt))
)
if value, ok := rdc.mutation.DependencyPackageID(); ok {
_spec.SetField(reportdependency.FieldDependencyPackageID, field.TypeString, value)
_node.DependencyPackageID = value
}
if value, ok := rdc.mutation.DependencyName(); ok {
_spec.SetField(reportdependency.FieldDependencyName, field.TypeString, value)
_node.DependencyName = value
}
if value, ok := rdc.mutation.DependencyVersion(); ok {
_spec.SetField(reportdependency.FieldDependencyVersion, field.TypeString, value)
_node.DependencyVersion = value
}
if value, ok := rdc.mutation.DependencyEcosystem(); ok {
_spec.SetField(reportdependency.FieldDependencyEcosystem, field.TypeString, value)
_node.DependencyEcosystem = value
}
if value, ok := rdc.mutation.DependencyType(); ok {
_spec.SetField(reportdependency.FieldDependencyType, field.TypeString, value)
_node.DependencyType = value
}
if value, ok := rdc.mutation.Depth(); ok {
_spec.SetField(reportdependency.FieldDepth, field.TypeInt, value)
_node.Depth = value
}
if value, ok := rdc.mutation.CreatedAt(); ok {
_spec.SetField(reportdependency.FieldCreatedAt, field.TypeTime, value)
_node.CreatedAt = value
}
if value, ok := rdc.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependency.FieldUpdatedAt, field.TypeTime, value)
_node.UpdatedAt = value
}
if nodes := rdc.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportdependency.PackageTable,
Columns: []string{reportdependency.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_node.report_package_dependencies = &nodes[0]
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}
// ReportDependencyCreateBulk is the builder for creating many ReportDependency entities in bulk.
type ReportDependencyCreateBulk struct {
config
err error
builders []*ReportDependencyCreate
}
// Save creates the ReportDependency entities in the database.
func (rdcb *ReportDependencyCreateBulk) Save(ctx context.Context) ([]*ReportDependency, error) {
if rdcb.err != nil {
return nil, rdcb.err
}
specs := make([]*sqlgraph.CreateSpec, len(rdcb.builders))
nodes := make([]*ReportDependency, len(rdcb.builders))
mutators := make([]Mutator, len(rdcb.builders))
for i := range rdcb.builders {
func(i int, root context.Context) {
builder := rdcb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ReportDependencyMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, rdcb.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, rdcb.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, rdcb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (rdcb *ReportDependencyCreateBulk) SaveX(ctx context.Context) []*ReportDependency {
v, err := rdcb.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rdcb *ReportDependencyCreateBulk) Exec(ctx context.Context) error {
_, err := rdcb.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdcb *ReportDependencyCreateBulk) ExecX(ctx context.Context) {
if err := rdcb.Exec(ctx); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependency"
)
// ReportDependencyDelete is the builder for deleting a ReportDependency entity.
type ReportDependencyDelete struct {
config
hooks []Hook
mutation *ReportDependencyMutation
}
// Where appends a list predicates to the ReportDependencyDelete builder.
func (rdd *ReportDependencyDelete) Where(ps ...predicate.ReportDependency) *ReportDependencyDelete {
rdd.mutation.Where(ps...)
return rdd
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (rdd *ReportDependencyDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, rdd.sqlExec, rdd.mutation, rdd.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (rdd *ReportDependencyDelete) ExecX(ctx context.Context) int {
n, err := rdd.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (rdd *ReportDependencyDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(reportdependency.Table, sqlgraph.NewFieldSpec(reportdependency.FieldID, field.TypeInt))
if ps := rdd.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, rdd.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
rdd.mutation.done = true
return affected, err
}
// ReportDependencyDeleteOne is the builder for deleting a single ReportDependency entity.
type ReportDependencyDeleteOne struct {
rdd *ReportDependencyDelete
}
// Where appends a list predicates to the ReportDependencyDelete builder.
func (rddo *ReportDependencyDeleteOne) Where(ps ...predicate.ReportDependency) *ReportDependencyDeleteOne {
rddo.rdd.mutation.Where(ps...)
return rddo
}
// Exec executes the deletion query.
func (rddo *ReportDependencyDeleteOne) Exec(ctx context.Context) error {
n, err := rddo.rdd.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{reportdependency.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (rddo *ReportDependencyDeleteOne) ExecX(ctx context.Context) {
if err := rddo.Exec(ctx); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,614 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependency"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportDependencyQuery is the builder for querying ReportDependency entities.
type ReportDependencyQuery struct {
config
ctx *QueryContext
order []reportdependency.OrderOption
inters []Interceptor
predicates []predicate.ReportDependency
withPackage *ReportPackageQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the ReportDependencyQuery builder.
func (rdq *ReportDependencyQuery) Where(ps ...predicate.ReportDependency) *ReportDependencyQuery {
rdq.predicates = append(rdq.predicates, ps...)
return rdq
}
// Limit the number of records to be returned by this query.
func (rdq *ReportDependencyQuery) Limit(limit int) *ReportDependencyQuery {
rdq.ctx.Limit = &limit
return rdq
}
// Offset to start from.
func (rdq *ReportDependencyQuery) Offset(offset int) *ReportDependencyQuery {
rdq.ctx.Offset = &offset
return rdq
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (rdq *ReportDependencyQuery) Unique(unique bool) *ReportDependencyQuery {
rdq.ctx.Unique = &unique
return rdq
}
// Order specifies how the records should be ordered.
func (rdq *ReportDependencyQuery) Order(o ...reportdependency.OrderOption) *ReportDependencyQuery {
rdq.order = append(rdq.order, o...)
return rdq
}
// QueryPackage chains the current query on the "package" edge.
func (rdq *ReportDependencyQuery) QueryPackage() *ReportPackageQuery {
query := (&ReportPackageClient{config: rdq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := rdq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := rdq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(reportdependency.Table, reportdependency.FieldID, selector),
sqlgraph.To(reportpackage.Table, reportpackage.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, reportdependency.PackageTable, reportdependency.PackageColumn),
)
fromU = sqlgraph.SetNeighbors(rdq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first ReportDependency entity from the query.
// Returns a *NotFoundError when no ReportDependency was found.
func (rdq *ReportDependencyQuery) First(ctx context.Context) (*ReportDependency, error) {
nodes, err := rdq.Limit(1).All(setContextOp(ctx, rdq.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{reportdependency.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (rdq *ReportDependencyQuery) FirstX(ctx context.Context) *ReportDependency {
node, err := rdq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first ReportDependency ID from the query.
// Returns a *NotFoundError when no ReportDependency ID was found.
func (rdq *ReportDependencyQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rdq.Limit(1).IDs(setContextOp(ctx, rdq.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{reportdependency.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (rdq *ReportDependencyQuery) FirstIDX(ctx context.Context) int {
id, err := rdq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single ReportDependency entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one ReportDependency entity is found.
// Returns a *NotFoundError when no ReportDependency entities are found.
func (rdq *ReportDependencyQuery) Only(ctx context.Context) (*ReportDependency, error) {
nodes, err := rdq.Limit(2).All(setContextOp(ctx, rdq.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{reportdependency.Label}
default:
return nil, &NotSingularError{reportdependency.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (rdq *ReportDependencyQuery) OnlyX(ctx context.Context) *ReportDependency {
node, err := rdq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only ReportDependency ID in the query.
// Returns a *NotSingularError when more than one ReportDependency ID is found.
// Returns a *NotFoundError when no entities are found.
func (rdq *ReportDependencyQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rdq.Limit(2).IDs(setContextOp(ctx, rdq.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{reportdependency.Label}
default:
err = &NotSingularError{reportdependency.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (rdq *ReportDependencyQuery) OnlyIDX(ctx context.Context) int {
id, err := rdq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of ReportDependencies.
func (rdq *ReportDependencyQuery) All(ctx context.Context) ([]*ReportDependency, error) {
ctx = setContextOp(ctx, rdq.ctx, ent.OpQueryAll)
if err := rdq.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*ReportDependency, *ReportDependencyQuery]()
return withInterceptors[[]*ReportDependency](ctx, rdq, qr, rdq.inters)
}
// AllX is like All, but panics if an error occurs.
func (rdq *ReportDependencyQuery) AllX(ctx context.Context) []*ReportDependency {
nodes, err := rdq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of ReportDependency IDs.
func (rdq *ReportDependencyQuery) IDs(ctx context.Context) (ids []int, err error) {
if rdq.ctx.Unique == nil && rdq.path != nil {
rdq.Unique(true)
}
ctx = setContextOp(ctx, rdq.ctx, ent.OpQueryIDs)
if err = rdq.Select(reportdependency.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (rdq *ReportDependencyQuery) IDsX(ctx context.Context) []int {
ids, err := rdq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (rdq *ReportDependencyQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, rdq.ctx, ent.OpQueryCount)
if err := rdq.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, rdq, querierCount[*ReportDependencyQuery](), rdq.inters)
}
// CountX is like Count, but panics if an error occurs.
func (rdq *ReportDependencyQuery) CountX(ctx context.Context) int {
count, err := rdq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (rdq *ReportDependencyQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, rdq.ctx, ent.OpQueryExist)
switch _, err := rdq.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (rdq *ReportDependencyQuery) ExistX(ctx context.Context) bool {
exist, err := rdq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the ReportDependencyQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (rdq *ReportDependencyQuery) Clone() *ReportDependencyQuery {
if rdq == nil {
return nil
}
return &ReportDependencyQuery{
config: rdq.config,
ctx: rdq.ctx.Clone(),
order: append([]reportdependency.OrderOption{}, rdq.order...),
inters: append([]Interceptor{}, rdq.inters...),
predicates: append([]predicate.ReportDependency{}, rdq.predicates...),
withPackage: rdq.withPackage.Clone(),
// clone intermediate query.
sql: rdq.sql.Clone(),
path: rdq.path,
}
}
// WithPackage tells the query-builder to eager-load the nodes that are connected to
// the "package" edge. The optional arguments are used to configure the query builder of the edge.
func (rdq *ReportDependencyQuery) WithPackage(opts ...func(*ReportPackageQuery)) *ReportDependencyQuery {
query := (&ReportPackageClient{config: rdq.config}).Query()
for _, opt := range opts {
opt(query)
}
rdq.withPackage = query
return rdq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// DependencyPackageID string `json:"dependency_package_id,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.ReportDependency.Query().
// GroupBy(reportdependency.FieldDependencyPackageID).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (rdq *ReportDependencyQuery) GroupBy(field string, fields ...string) *ReportDependencyGroupBy {
rdq.ctx.Fields = append([]string{field}, fields...)
grbuild := &ReportDependencyGroupBy{build: rdq}
grbuild.flds = &rdq.ctx.Fields
grbuild.label = reportdependency.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// DependencyPackageID string `json:"dependency_package_id,omitempty"`
// }
//
// client.ReportDependency.Query().
// Select(reportdependency.FieldDependencyPackageID).
// Scan(ctx, &v)
func (rdq *ReportDependencyQuery) Select(fields ...string) *ReportDependencySelect {
rdq.ctx.Fields = append(rdq.ctx.Fields, fields...)
sbuild := &ReportDependencySelect{ReportDependencyQuery: rdq}
sbuild.label = reportdependency.Label
sbuild.flds, sbuild.scan = &rdq.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a ReportDependencySelect configured with the given aggregations.
func (rdq *ReportDependencyQuery) Aggregate(fns ...AggregateFunc) *ReportDependencySelect {
return rdq.Select().Aggregate(fns...)
}
func (rdq *ReportDependencyQuery) prepareQuery(ctx context.Context) error {
for _, inter := range rdq.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, rdq); err != nil {
return err
}
}
}
for _, f := range rdq.ctx.Fields {
if !reportdependency.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if rdq.path != nil {
prev, err := rdq.path(ctx)
if err != nil {
return err
}
rdq.sql = prev
}
return nil
}
func (rdq *ReportDependencyQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ReportDependency, error) {
var (
nodes = []*ReportDependency{}
withFKs = rdq.withFKs
_spec = rdq.querySpec()
loadedTypes = [1]bool{
rdq.withPackage != nil,
}
)
if rdq.withPackage != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, reportdependency.ForeignKeys...)
}
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*ReportDependency).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &ReportDependency{config: rdq.config}
nodes = append(nodes, node)
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, rdq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := rdq.withPackage; query != nil {
if err := rdq.loadPackage(ctx, query, nodes, nil,
func(n *ReportDependency, e *ReportPackage) { n.Edges.Package = e }); err != nil {
return nil, err
}
}
return nodes, nil
}
func (rdq *ReportDependencyQuery) loadPackage(ctx context.Context, query *ReportPackageQuery, nodes []*ReportDependency, init func(*ReportDependency), assign func(*ReportDependency, *ReportPackage)) error {
ids := make([]int, 0, len(nodes))
nodeids := make(map[int][]*ReportDependency)
for i := range nodes {
if nodes[i].report_package_dependencies == nil {
continue
}
fk := *nodes[i].report_package_dependencies
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(reportpackage.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "report_package_dependencies" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (rdq *ReportDependencyQuery) sqlCount(ctx context.Context) (int, error) {
_spec := rdq.querySpec()
_spec.Node.Columns = rdq.ctx.Fields
if len(rdq.ctx.Fields) > 0 {
_spec.Unique = rdq.ctx.Unique != nil && *rdq.ctx.Unique
}
return sqlgraph.CountNodes(ctx, rdq.driver, _spec)
}
func (rdq *ReportDependencyQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(reportdependency.Table, reportdependency.Columns, sqlgraph.NewFieldSpec(reportdependency.FieldID, field.TypeInt))
_spec.From = rdq.sql
if unique := rdq.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if rdq.path != nil {
_spec.Unique = true
}
if fields := rdq.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportdependency.FieldID)
for i := range fields {
if fields[i] != reportdependency.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := rdq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := rdq.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := rdq.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := rdq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (rdq *ReportDependencyQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(rdq.driver.Dialect())
t1 := builder.Table(reportdependency.Table)
columns := rdq.ctx.Fields
if len(columns) == 0 {
columns = reportdependency.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if rdq.sql != nil {
selector = rdq.sql
selector.Select(selector.Columns(columns...)...)
}
if rdq.ctx.Unique != nil && *rdq.ctx.Unique {
selector.Distinct()
}
for _, p := range rdq.predicates {
p(selector)
}
for _, p := range rdq.order {
p(selector)
}
if offset := rdq.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := rdq.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ReportDependencyGroupBy is the group-by builder for ReportDependency entities.
type ReportDependencyGroupBy struct {
selector
build *ReportDependencyQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (rdgb *ReportDependencyGroupBy) Aggregate(fns ...AggregateFunc) *ReportDependencyGroupBy {
rdgb.fns = append(rdgb.fns, fns...)
return rdgb
}
// Scan applies the selector query and scans the result into the given value.
func (rdgb *ReportDependencyGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rdgb.build.ctx, ent.OpQueryGroupBy)
if err := rdgb.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportDependencyQuery, *ReportDependencyGroupBy](ctx, rdgb.build, rdgb, rdgb.build.inters, v)
}
func (rdgb *ReportDependencyGroupBy) sqlScan(ctx context.Context, root *ReportDependencyQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(rdgb.fns))
for _, fn := range rdgb.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*rdgb.flds)+len(rdgb.fns))
for _, f := range *rdgb.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*rdgb.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rdgb.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// ReportDependencySelect is the builder for selecting fields of ReportDependency entities.
type ReportDependencySelect struct {
*ReportDependencyQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (rds *ReportDependencySelect) Aggregate(fns ...AggregateFunc) *ReportDependencySelect {
rds.fns = append(rds.fns, fns...)
return rds
}
// Scan applies the selector query and scans the result into the given value.
func (rds *ReportDependencySelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rds.ctx, ent.OpQuerySelect)
if err := rds.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportDependencyQuery, *ReportDependencySelect](ctx, rds.ReportDependencyQuery, rds, rds.inters, v)
}
func (rds *ReportDependencySelect) sqlScan(ctx context.Context, root *ReportDependencyQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(rds.fns))
for _, fn := range rds.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*rds.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rds.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}

View File

@ -0,0 +1,687 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependency"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportDependencyUpdate is the builder for updating ReportDependency entities.
type ReportDependencyUpdate struct {
config
hooks []Hook
mutation *ReportDependencyMutation
}
// Where appends a list predicates to the ReportDependencyUpdate builder.
func (rdu *ReportDependencyUpdate) Where(ps ...predicate.ReportDependency) *ReportDependencyUpdate {
rdu.mutation.Where(ps...)
return rdu
}
// SetDependencyPackageID sets the "dependency_package_id" field.
func (rdu *ReportDependencyUpdate) SetDependencyPackageID(s string) *ReportDependencyUpdate {
rdu.mutation.SetDependencyPackageID(s)
return rdu
}
// SetNillableDependencyPackageID sets the "dependency_package_id" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDependencyPackageID(s *string) *ReportDependencyUpdate {
if s != nil {
rdu.SetDependencyPackageID(*s)
}
return rdu
}
// SetDependencyName sets the "dependency_name" field.
func (rdu *ReportDependencyUpdate) SetDependencyName(s string) *ReportDependencyUpdate {
rdu.mutation.SetDependencyName(s)
return rdu
}
// SetNillableDependencyName sets the "dependency_name" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDependencyName(s *string) *ReportDependencyUpdate {
if s != nil {
rdu.SetDependencyName(*s)
}
return rdu
}
// SetDependencyVersion sets the "dependency_version" field.
func (rdu *ReportDependencyUpdate) SetDependencyVersion(s string) *ReportDependencyUpdate {
rdu.mutation.SetDependencyVersion(s)
return rdu
}
// SetNillableDependencyVersion sets the "dependency_version" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDependencyVersion(s *string) *ReportDependencyUpdate {
if s != nil {
rdu.SetDependencyVersion(*s)
}
return rdu
}
// SetDependencyEcosystem sets the "dependency_ecosystem" field.
func (rdu *ReportDependencyUpdate) SetDependencyEcosystem(s string) *ReportDependencyUpdate {
rdu.mutation.SetDependencyEcosystem(s)
return rdu
}
// SetNillableDependencyEcosystem sets the "dependency_ecosystem" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDependencyEcosystem(s *string) *ReportDependencyUpdate {
if s != nil {
rdu.SetDependencyEcosystem(*s)
}
return rdu
}
// SetDependencyType sets the "dependency_type" field.
func (rdu *ReportDependencyUpdate) SetDependencyType(s string) *ReportDependencyUpdate {
rdu.mutation.SetDependencyType(s)
return rdu
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDependencyType(s *string) *ReportDependencyUpdate {
if s != nil {
rdu.SetDependencyType(*s)
}
return rdu
}
// ClearDependencyType clears the value of the "dependency_type" field.
func (rdu *ReportDependencyUpdate) ClearDependencyType() *ReportDependencyUpdate {
rdu.mutation.ClearDependencyType()
return rdu
}
// SetDepth sets the "depth" field.
func (rdu *ReportDependencyUpdate) SetDepth(i int) *ReportDependencyUpdate {
rdu.mutation.ResetDepth()
rdu.mutation.SetDepth(i)
return rdu
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableDepth(i *int) *ReportDependencyUpdate {
if i != nil {
rdu.SetDepth(*i)
}
return rdu
}
// AddDepth adds i to the "depth" field.
func (rdu *ReportDependencyUpdate) AddDepth(i int) *ReportDependencyUpdate {
rdu.mutation.AddDepth(i)
return rdu
}
// SetCreatedAt sets the "created_at" field.
func (rdu *ReportDependencyUpdate) SetCreatedAt(t time.Time) *ReportDependencyUpdate {
rdu.mutation.SetCreatedAt(t)
return rdu
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableCreatedAt(t *time.Time) *ReportDependencyUpdate {
if t != nil {
rdu.SetCreatedAt(*t)
}
return rdu
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rdu *ReportDependencyUpdate) ClearCreatedAt() *ReportDependencyUpdate {
rdu.mutation.ClearCreatedAt()
return rdu
}
// SetUpdatedAt sets the "updated_at" field.
func (rdu *ReportDependencyUpdate) SetUpdatedAt(t time.Time) *ReportDependencyUpdate {
rdu.mutation.SetUpdatedAt(t)
return rdu
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillableUpdatedAt(t *time.Time) *ReportDependencyUpdate {
if t != nil {
rdu.SetUpdatedAt(*t)
}
return rdu
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rdu *ReportDependencyUpdate) ClearUpdatedAt() *ReportDependencyUpdate {
rdu.mutation.ClearUpdatedAt()
return rdu
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rdu *ReportDependencyUpdate) SetPackageID(id int) *ReportDependencyUpdate {
rdu.mutation.SetPackageID(id)
return rdu
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rdu *ReportDependencyUpdate) SetNillablePackageID(id *int) *ReportDependencyUpdate {
if id != nil {
rdu = rdu.SetPackageID(*id)
}
return rdu
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rdu *ReportDependencyUpdate) SetPackage(r *ReportPackage) *ReportDependencyUpdate {
return rdu.SetPackageID(r.ID)
}
// Mutation returns the ReportDependencyMutation object of the builder.
func (rdu *ReportDependencyUpdate) Mutation() *ReportDependencyMutation {
return rdu.mutation
}
// ClearPackage clears the "package" edge to the ReportPackage entity.
func (rdu *ReportDependencyUpdate) ClearPackage() *ReportDependencyUpdate {
rdu.mutation.ClearPackage()
return rdu
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (rdu *ReportDependencyUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, rdu.sqlSave, rdu.mutation, rdu.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rdu *ReportDependencyUpdate) SaveX(ctx context.Context) int {
affected, err := rdu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (rdu *ReportDependencyUpdate) Exec(ctx context.Context) error {
_, err := rdu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdu *ReportDependencyUpdate) ExecX(ctx context.Context) {
if err := rdu.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rdu *ReportDependencyUpdate) check() error {
if v, ok := rdu.mutation.DependencyPackageID(); ok {
if err := reportdependency.DependencyPackageIDValidator(v); err != nil {
return &ValidationError{Name: "dependency_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_package_id": %w`, err)}
}
}
if v, ok := rdu.mutation.DependencyName(); ok {
if err := reportdependency.DependencyNameValidator(v); err != nil {
return &ValidationError{Name: "dependency_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_name": %w`, err)}
}
}
if v, ok := rdu.mutation.DependencyVersion(); ok {
if err := reportdependency.DependencyVersionValidator(v); err != nil {
return &ValidationError{Name: "dependency_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_version": %w`, err)}
}
}
if v, ok := rdu.mutation.DependencyEcosystem(); ok {
if err := reportdependency.DependencyEcosystemValidator(v); err != nil {
return &ValidationError{Name: "dependency_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_ecosystem": %w`, err)}
}
}
return nil
}
func (rdu *ReportDependencyUpdate) sqlSave(ctx context.Context) (n int, err error) {
if err := rdu.check(); err != nil {
return n, err
}
_spec := sqlgraph.NewUpdateSpec(reportdependency.Table, reportdependency.Columns, sqlgraph.NewFieldSpec(reportdependency.FieldID, field.TypeInt))
if ps := rdu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rdu.mutation.DependencyPackageID(); ok {
_spec.SetField(reportdependency.FieldDependencyPackageID, field.TypeString, value)
}
if value, ok := rdu.mutation.DependencyName(); ok {
_spec.SetField(reportdependency.FieldDependencyName, field.TypeString, value)
}
if value, ok := rdu.mutation.DependencyVersion(); ok {
_spec.SetField(reportdependency.FieldDependencyVersion, field.TypeString, value)
}
if value, ok := rdu.mutation.DependencyEcosystem(); ok {
_spec.SetField(reportdependency.FieldDependencyEcosystem, field.TypeString, value)
}
if value, ok := rdu.mutation.DependencyType(); ok {
_spec.SetField(reportdependency.FieldDependencyType, field.TypeString, value)
}
if rdu.mutation.DependencyTypeCleared() {
_spec.ClearField(reportdependency.FieldDependencyType, field.TypeString)
}
if value, ok := rdu.mutation.Depth(); ok {
_spec.SetField(reportdependency.FieldDepth, field.TypeInt, value)
}
if value, ok := rdu.mutation.AddedDepth(); ok {
_spec.AddField(reportdependency.FieldDepth, field.TypeInt, value)
}
if value, ok := rdu.mutation.CreatedAt(); ok {
_spec.SetField(reportdependency.FieldCreatedAt, field.TypeTime, value)
}
if rdu.mutation.CreatedAtCleared() {
_spec.ClearField(reportdependency.FieldCreatedAt, field.TypeTime)
}
if value, ok := rdu.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependency.FieldUpdatedAt, field.TypeTime, value)
}
if rdu.mutation.UpdatedAtCleared() {
_spec.ClearField(reportdependency.FieldUpdatedAt, field.TypeTime)
}
if rdu.mutation.PackageCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportdependency.PackageTable,
Columns: []string{reportdependency.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := rdu.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportdependency.PackageTable,
Columns: []string{reportdependency.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, rdu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportdependency.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
rdu.mutation.done = true
return n, nil
}
// ReportDependencyUpdateOne is the builder for updating a single ReportDependency entity.
type ReportDependencyUpdateOne struct {
config
fields []string
hooks []Hook
mutation *ReportDependencyMutation
}
// SetDependencyPackageID sets the "dependency_package_id" field.
func (rduo *ReportDependencyUpdateOne) SetDependencyPackageID(s string) *ReportDependencyUpdateOne {
rduo.mutation.SetDependencyPackageID(s)
return rduo
}
// SetNillableDependencyPackageID sets the "dependency_package_id" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDependencyPackageID(s *string) *ReportDependencyUpdateOne {
if s != nil {
rduo.SetDependencyPackageID(*s)
}
return rduo
}
// SetDependencyName sets the "dependency_name" field.
func (rduo *ReportDependencyUpdateOne) SetDependencyName(s string) *ReportDependencyUpdateOne {
rduo.mutation.SetDependencyName(s)
return rduo
}
// SetNillableDependencyName sets the "dependency_name" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDependencyName(s *string) *ReportDependencyUpdateOne {
if s != nil {
rduo.SetDependencyName(*s)
}
return rduo
}
// SetDependencyVersion sets the "dependency_version" field.
func (rduo *ReportDependencyUpdateOne) SetDependencyVersion(s string) *ReportDependencyUpdateOne {
rduo.mutation.SetDependencyVersion(s)
return rduo
}
// SetNillableDependencyVersion sets the "dependency_version" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDependencyVersion(s *string) *ReportDependencyUpdateOne {
if s != nil {
rduo.SetDependencyVersion(*s)
}
return rduo
}
// SetDependencyEcosystem sets the "dependency_ecosystem" field.
func (rduo *ReportDependencyUpdateOne) SetDependencyEcosystem(s string) *ReportDependencyUpdateOne {
rduo.mutation.SetDependencyEcosystem(s)
return rduo
}
// SetNillableDependencyEcosystem sets the "dependency_ecosystem" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDependencyEcosystem(s *string) *ReportDependencyUpdateOne {
if s != nil {
rduo.SetDependencyEcosystem(*s)
}
return rduo
}
// SetDependencyType sets the "dependency_type" field.
func (rduo *ReportDependencyUpdateOne) SetDependencyType(s string) *ReportDependencyUpdateOne {
rduo.mutation.SetDependencyType(s)
return rduo
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDependencyType(s *string) *ReportDependencyUpdateOne {
if s != nil {
rduo.SetDependencyType(*s)
}
return rduo
}
// ClearDependencyType clears the value of the "dependency_type" field.
func (rduo *ReportDependencyUpdateOne) ClearDependencyType() *ReportDependencyUpdateOne {
rduo.mutation.ClearDependencyType()
return rduo
}
// SetDepth sets the "depth" field.
func (rduo *ReportDependencyUpdateOne) SetDepth(i int) *ReportDependencyUpdateOne {
rduo.mutation.ResetDepth()
rduo.mutation.SetDepth(i)
return rduo
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableDepth(i *int) *ReportDependencyUpdateOne {
if i != nil {
rduo.SetDepth(*i)
}
return rduo
}
// AddDepth adds i to the "depth" field.
func (rduo *ReportDependencyUpdateOne) AddDepth(i int) *ReportDependencyUpdateOne {
rduo.mutation.AddDepth(i)
return rduo
}
// SetCreatedAt sets the "created_at" field.
func (rduo *ReportDependencyUpdateOne) SetCreatedAt(t time.Time) *ReportDependencyUpdateOne {
rduo.mutation.SetCreatedAt(t)
return rduo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableCreatedAt(t *time.Time) *ReportDependencyUpdateOne {
if t != nil {
rduo.SetCreatedAt(*t)
}
return rduo
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rduo *ReportDependencyUpdateOne) ClearCreatedAt() *ReportDependencyUpdateOne {
rduo.mutation.ClearCreatedAt()
return rduo
}
// SetUpdatedAt sets the "updated_at" field.
func (rduo *ReportDependencyUpdateOne) SetUpdatedAt(t time.Time) *ReportDependencyUpdateOne {
rduo.mutation.SetUpdatedAt(t)
return rduo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillableUpdatedAt(t *time.Time) *ReportDependencyUpdateOne {
if t != nil {
rduo.SetUpdatedAt(*t)
}
return rduo
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rduo *ReportDependencyUpdateOne) ClearUpdatedAt() *ReportDependencyUpdateOne {
rduo.mutation.ClearUpdatedAt()
return rduo
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rduo *ReportDependencyUpdateOne) SetPackageID(id int) *ReportDependencyUpdateOne {
rduo.mutation.SetPackageID(id)
return rduo
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rduo *ReportDependencyUpdateOne) SetNillablePackageID(id *int) *ReportDependencyUpdateOne {
if id != nil {
rduo = rduo.SetPackageID(*id)
}
return rduo
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rduo *ReportDependencyUpdateOne) SetPackage(r *ReportPackage) *ReportDependencyUpdateOne {
return rduo.SetPackageID(r.ID)
}
// Mutation returns the ReportDependencyMutation object of the builder.
func (rduo *ReportDependencyUpdateOne) Mutation() *ReportDependencyMutation {
return rduo.mutation
}
// ClearPackage clears the "package" edge to the ReportPackage entity.
func (rduo *ReportDependencyUpdateOne) ClearPackage() *ReportDependencyUpdateOne {
rduo.mutation.ClearPackage()
return rduo
}
// Where appends a list predicates to the ReportDependencyUpdate builder.
func (rduo *ReportDependencyUpdateOne) Where(ps ...predicate.ReportDependency) *ReportDependencyUpdateOne {
rduo.mutation.Where(ps...)
return rduo
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (rduo *ReportDependencyUpdateOne) Select(field string, fields ...string) *ReportDependencyUpdateOne {
rduo.fields = append([]string{field}, fields...)
return rduo
}
// Save executes the query and returns the updated ReportDependency entity.
func (rduo *ReportDependencyUpdateOne) Save(ctx context.Context) (*ReportDependency, error) {
return withHooks(ctx, rduo.sqlSave, rduo.mutation, rduo.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rduo *ReportDependencyUpdateOne) SaveX(ctx context.Context) *ReportDependency {
node, err := rduo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (rduo *ReportDependencyUpdateOne) Exec(ctx context.Context) error {
_, err := rduo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rduo *ReportDependencyUpdateOne) ExecX(ctx context.Context) {
if err := rduo.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rduo *ReportDependencyUpdateOne) check() error {
if v, ok := rduo.mutation.DependencyPackageID(); ok {
if err := reportdependency.DependencyPackageIDValidator(v); err != nil {
return &ValidationError{Name: "dependency_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_package_id": %w`, err)}
}
}
if v, ok := rduo.mutation.DependencyName(); ok {
if err := reportdependency.DependencyNameValidator(v); err != nil {
return &ValidationError{Name: "dependency_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_name": %w`, err)}
}
}
if v, ok := rduo.mutation.DependencyVersion(); ok {
if err := reportdependency.DependencyVersionValidator(v); err != nil {
return &ValidationError{Name: "dependency_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_version": %w`, err)}
}
}
if v, ok := rduo.mutation.DependencyEcosystem(); ok {
if err := reportdependency.DependencyEcosystemValidator(v); err != nil {
return &ValidationError{Name: "dependency_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependency.dependency_ecosystem": %w`, err)}
}
}
return nil
}
func (rduo *ReportDependencyUpdateOne) sqlSave(ctx context.Context) (_node *ReportDependency, err error) {
if err := rduo.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(reportdependency.Table, reportdependency.Columns, sqlgraph.NewFieldSpec(reportdependency.FieldID, field.TypeInt))
id, ok := rduo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ReportDependency.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := rduo.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportdependency.FieldID)
for _, f := range fields {
if !reportdependency.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != reportdependency.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := rduo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rduo.mutation.DependencyPackageID(); ok {
_spec.SetField(reportdependency.FieldDependencyPackageID, field.TypeString, value)
}
if value, ok := rduo.mutation.DependencyName(); ok {
_spec.SetField(reportdependency.FieldDependencyName, field.TypeString, value)
}
if value, ok := rduo.mutation.DependencyVersion(); ok {
_spec.SetField(reportdependency.FieldDependencyVersion, field.TypeString, value)
}
if value, ok := rduo.mutation.DependencyEcosystem(); ok {
_spec.SetField(reportdependency.FieldDependencyEcosystem, field.TypeString, value)
}
if value, ok := rduo.mutation.DependencyType(); ok {
_spec.SetField(reportdependency.FieldDependencyType, field.TypeString, value)
}
if rduo.mutation.DependencyTypeCleared() {
_spec.ClearField(reportdependency.FieldDependencyType, field.TypeString)
}
if value, ok := rduo.mutation.Depth(); ok {
_spec.SetField(reportdependency.FieldDepth, field.TypeInt, value)
}
if value, ok := rduo.mutation.AddedDepth(); ok {
_spec.AddField(reportdependency.FieldDepth, field.TypeInt, value)
}
if value, ok := rduo.mutation.CreatedAt(); ok {
_spec.SetField(reportdependency.FieldCreatedAt, field.TypeTime, value)
}
if rduo.mutation.CreatedAtCleared() {
_spec.ClearField(reportdependency.FieldCreatedAt, field.TypeTime)
}
if value, ok := rduo.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependency.FieldUpdatedAt, field.TypeTime, value)
}
if rduo.mutation.UpdatedAtCleared() {
_spec.ClearField(reportdependency.FieldUpdatedAt, field.TypeTime)
}
if rduo.mutation.PackageCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportdependency.PackageTable,
Columns: []string{reportdependency.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := rduo.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportdependency.PackageTable,
Columns: []string{reportdependency.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &ReportDependency{config: rduo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, rduo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportdependency.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
rduo.mutation.done = true
return _node, nil
}

View File

@ -0,0 +1,273 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/safedep/vet/ent/reportdependencygraph"
)
// ReportDependencyGraph is the model entity for the ReportDependencyGraph schema.
type ReportDependencyGraph struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// Reference to ReportPackage.package_id
FromPackageID string `json:"from_package_id,omitempty"`
// FromPackageName holds the value of the "from_package_name" field.
FromPackageName string `json:"from_package_name,omitempty"`
// FromPackageVersion holds the value of the "from_package_version" field.
FromPackageVersion string `json:"from_package_version,omitempty"`
// FromPackageEcosystem holds the value of the "from_package_ecosystem" field.
FromPackageEcosystem string `json:"from_package_ecosystem,omitempty"`
// Reference to ReportPackage.package_id
ToPackageID string `json:"to_package_id,omitempty"`
// ToPackageName holds the value of the "to_package_name" field.
ToPackageName string `json:"to_package_name,omitempty"`
// ToPackageVersion holds the value of the "to_package_version" field.
ToPackageVersion string `json:"to_package_version,omitempty"`
// ToPackageEcosystem holds the value of the "to_package_ecosystem" field.
ToPackageEcosystem string `json:"to_package_ecosystem,omitempty"`
// e.g., runtime, dev, optional
DependencyType string `json:"dependency_type,omitempty"`
// e.g., ^1.2.3, >=2.0.0
VersionConstraint string `json:"version_constraint,omitempty"`
// Depth in dependency tree
Depth int `json:"depth,omitempty"`
// Direct dependency from manifest
IsDirect bool `json:"is_direct,omitempty"`
// Edge from root package
IsRootEdge bool `json:"is_root_edge,omitempty"`
// Manifest where this edge was discovered
ManifestID string `json:"manifest_id,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
selectValues sql.SelectValues
}
// scanValues returns the types for scanning values from sql.Rows.
func (*ReportDependencyGraph) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case reportdependencygraph.FieldIsDirect, reportdependencygraph.FieldIsRootEdge:
values[i] = new(sql.NullBool)
case reportdependencygraph.FieldID, reportdependencygraph.FieldDepth:
values[i] = new(sql.NullInt64)
case reportdependencygraph.FieldFromPackageID, reportdependencygraph.FieldFromPackageName, reportdependencygraph.FieldFromPackageVersion, reportdependencygraph.FieldFromPackageEcosystem, reportdependencygraph.FieldToPackageID, reportdependencygraph.FieldToPackageName, reportdependencygraph.FieldToPackageVersion, reportdependencygraph.FieldToPackageEcosystem, reportdependencygraph.FieldDependencyType, reportdependencygraph.FieldVersionConstraint, reportdependencygraph.FieldManifestID:
values[i] = new(sql.NullString)
case reportdependencygraph.FieldCreatedAt, reportdependencygraph.FieldUpdatedAt:
values[i] = new(sql.NullTime)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the ReportDependencyGraph fields.
func (rdg *ReportDependencyGraph) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case reportdependencygraph.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
rdg.ID = int(value.Int64)
case reportdependencygraph.FieldFromPackageID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field from_package_id", values[i])
} else if value.Valid {
rdg.FromPackageID = value.String
}
case reportdependencygraph.FieldFromPackageName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field from_package_name", values[i])
} else if value.Valid {
rdg.FromPackageName = value.String
}
case reportdependencygraph.FieldFromPackageVersion:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field from_package_version", values[i])
} else if value.Valid {
rdg.FromPackageVersion = value.String
}
case reportdependencygraph.FieldFromPackageEcosystem:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field from_package_ecosystem", values[i])
} else if value.Valid {
rdg.FromPackageEcosystem = value.String
}
case reportdependencygraph.FieldToPackageID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field to_package_id", values[i])
} else if value.Valid {
rdg.ToPackageID = value.String
}
case reportdependencygraph.FieldToPackageName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field to_package_name", values[i])
} else if value.Valid {
rdg.ToPackageName = value.String
}
case reportdependencygraph.FieldToPackageVersion:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field to_package_version", values[i])
} else if value.Valid {
rdg.ToPackageVersion = value.String
}
case reportdependencygraph.FieldToPackageEcosystem:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field to_package_ecosystem", values[i])
} else if value.Valid {
rdg.ToPackageEcosystem = value.String
}
case reportdependencygraph.FieldDependencyType:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field dependency_type", values[i])
} else if value.Valid {
rdg.DependencyType = value.String
}
case reportdependencygraph.FieldVersionConstraint:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field version_constraint", values[i])
} else if value.Valid {
rdg.VersionConstraint = value.String
}
case reportdependencygraph.FieldDepth:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for field depth", values[i])
} else if value.Valid {
rdg.Depth = int(value.Int64)
}
case reportdependencygraph.FieldIsDirect:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field is_direct", values[i])
} else if value.Valid {
rdg.IsDirect = value.Bool
}
case reportdependencygraph.FieldIsRootEdge:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field is_root_edge", values[i])
} else if value.Valid {
rdg.IsRootEdge = value.Bool
}
case reportdependencygraph.FieldManifestID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field manifest_id", values[i])
} else if value.Valid {
rdg.ManifestID = value.String
}
case reportdependencygraph.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
rdg.CreatedAt = value.Time
}
case reportdependencygraph.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
rdg.UpdatedAt = value.Time
}
default:
rdg.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the ReportDependencyGraph.
// This includes values selected through modifiers, order, etc.
func (rdg *ReportDependencyGraph) Value(name string) (ent.Value, error) {
return rdg.selectValues.Get(name)
}
// Update returns a builder for updating this ReportDependencyGraph.
// Note that you need to call ReportDependencyGraph.Unwrap() before calling this method if this ReportDependencyGraph
// was returned from a transaction, and the transaction was committed or rolled back.
func (rdg *ReportDependencyGraph) Update() *ReportDependencyGraphUpdateOne {
return NewReportDependencyGraphClient(rdg.config).UpdateOne(rdg)
}
// Unwrap unwraps the ReportDependencyGraph entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (rdg *ReportDependencyGraph) Unwrap() *ReportDependencyGraph {
_tx, ok := rdg.config.driver.(*txDriver)
if !ok {
panic("ent: ReportDependencyGraph is not a transactional entity")
}
rdg.config.driver = _tx.drv
return rdg
}
// String implements the fmt.Stringer.
func (rdg *ReportDependencyGraph) String() string {
var builder strings.Builder
builder.WriteString("ReportDependencyGraph(")
builder.WriteString(fmt.Sprintf("id=%v, ", rdg.ID))
builder.WriteString("from_package_id=")
builder.WriteString(rdg.FromPackageID)
builder.WriteString(", ")
builder.WriteString("from_package_name=")
builder.WriteString(rdg.FromPackageName)
builder.WriteString(", ")
builder.WriteString("from_package_version=")
builder.WriteString(rdg.FromPackageVersion)
builder.WriteString(", ")
builder.WriteString("from_package_ecosystem=")
builder.WriteString(rdg.FromPackageEcosystem)
builder.WriteString(", ")
builder.WriteString("to_package_id=")
builder.WriteString(rdg.ToPackageID)
builder.WriteString(", ")
builder.WriteString("to_package_name=")
builder.WriteString(rdg.ToPackageName)
builder.WriteString(", ")
builder.WriteString("to_package_version=")
builder.WriteString(rdg.ToPackageVersion)
builder.WriteString(", ")
builder.WriteString("to_package_ecosystem=")
builder.WriteString(rdg.ToPackageEcosystem)
builder.WriteString(", ")
builder.WriteString("dependency_type=")
builder.WriteString(rdg.DependencyType)
builder.WriteString(", ")
builder.WriteString("version_constraint=")
builder.WriteString(rdg.VersionConstraint)
builder.WriteString(", ")
builder.WriteString("depth=")
builder.WriteString(fmt.Sprintf("%v", rdg.Depth))
builder.WriteString(", ")
builder.WriteString("is_direct=")
builder.WriteString(fmt.Sprintf("%v", rdg.IsDirect))
builder.WriteString(", ")
builder.WriteString("is_root_edge=")
builder.WriteString(fmt.Sprintf("%v", rdg.IsRootEdge))
builder.WriteString(", ")
builder.WriteString("manifest_id=")
builder.WriteString(rdg.ManifestID)
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(rdg.CreatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(rdg.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// ReportDependencyGraphs is a parsable slice of ReportDependencyGraph.
type ReportDependencyGraphs []*ReportDependencyGraph

View File

@ -0,0 +1,194 @@
// Code generated by ent, DO NOT EDIT.
package reportdependencygraph
import (
"entgo.io/ent/dialect/sql"
)
const (
// Label holds the string label denoting the reportdependencygraph type in the database.
Label = "report_dependency_graph"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldFromPackageID holds the string denoting the from_package_id field in the database.
FieldFromPackageID = "from_package_id"
// FieldFromPackageName holds the string denoting the from_package_name field in the database.
FieldFromPackageName = "from_package_name"
// FieldFromPackageVersion holds the string denoting the from_package_version field in the database.
FieldFromPackageVersion = "from_package_version"
// FieldFromPackageEcosystem holds the string denoting the from_package_ecosystem field in the database.
FieldFromPackageEcosystem = "from_package_ecosystem"
// FieldToPackageID holds the string denoting the to_package_id field in the database.
FieldToPackageID = "to_package_id"
// FieldToPackageName holds the string denoting the to_package_name field in the database.
FieldToPackageName = "to_package_name"
// FieldToPackageVersion holds the string denoting the to_package_version field in the database.
FieldToPackageVersion = "to_package_version"
// FieldToPackageEcosystem holds the string denoting the to_package_ecosystem field in the database.
FieldToPackageEcosystem = "to_package_ecosystem"
// FieldDependencyType holds the string denoting the dependency_type field in the database.
FieldDependencyType = "dependency_type"
// FieldVersionConstraint holds the string denoting the version_constraint field in the database.
FieldVersionConstraint = "version_constraint"
// FieldDepth holds the string denoting the depth field in the database.
FieldDepth = "depth"
// FieldIsDirect holds the string denoting the is_direct field in the database.
FieldIsDirect = "is_direct"
// FieldIsRootEdge holds the string denoting the is_root_edge field in the database.
FieldIsRootEdge = "is_root_edge"
// FieldManifestID holds the string denoting the manifest_id field in the database.
FieldManifestID = "manifest_id"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// Table holds the table name of the reportdependencygraph in the database.
Table = "report_dependency_graphs"
)
// Columns holds all SQL columns for reportdependencygraph fields.
var Columns = []string{
FieldID,
FieldFromPackageID,
FieldFromPackageName,
FieldFromPackageVersion,
FieldFromPackageEcosystem,
FieldToPackageID,
FieldToPackageName,
FieldToPackageVersion,
FieldToPackageEcosystem,
FieldDependencyType,
FieldVersionConstraint,
FieldDepth,
FieldIsDirect,
FieldIsRootEdge,
FieldManifestID,
FieldCreatedAt,
FieldUpdatedAt,
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
return false
}
var (
// FromPackageIDValidator is a validator for the "from_package_id" field. It is called by the builders before save.
FromPackageIDValidator func(string) error
// FromPackageNameValidator is a validator for the "from_package_name" field. It is called by the builders before save.
FromPackageNameValidator func(string) error
// FromPackageVersionValidator is a validator for the "from_package_version" field. It is called by the builders before save.
FromPackageVersionValidator func(string) error
// FromPackageEcosystemValidator is a validator for the "from_package_ecosystem" field. It is called by the builders before save.
FromPackageEcosystemValidator func(string) error
// ToPackageIDValidator is a validator for the "to_package_id" field. It is called by the builders before save.
ToPackageIDValidator func(string) error
// ToPackageNameValidator is a validator for the "to_package_name" field. It is called by the builders before save.
ToPackageNameValidator func(string) error
// ToPackageVersionValidator is a validator for the "to_package_version" field. It is called by the builders before save.
ToPackageVersionValidator func(string) error
// ToPackageEcosystemValidator is a validator for the "to_package_ecosystem" field. It is called by the builders before save.
ToPackageEcosystemValidator func(string) error
// DefaultDepth holds the default value on creation for the "depth" field.
DefaultDepth int
// DefaultIsDirect holds the default value on creation for the "is_direct" field.
DefaultIsDirect bool
// DefaultIsRootEdge holds the default value on creation for the "is_root_edge" field.
DefaultIsRootEdge bool
// ManifestIDValidator is a validator for the "manifest_id" field. It is called by the builders before save.
ManifestIDValidator func(string) error
)
// OrderOption defines the ordering options for the ReportDependencyGraph queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByFromPackageID orders the results by the from_package_id field.
func ByFromPackageID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldFromPackageID, opts...).ToFunc()
}
// ByFromPackageName orders the results by the from_package_name field.
func ByFromPackageName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldFromPackageName, opts...).ToFunc()
}
// ByFromPackageVersion orders the results by the from_package_version field.
func ByFromPackageVersion(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldFromPackageVersion, opts...).ToFunc()
}
// ByFromPackageEcosystem orders the results by the from_package_ecosystem field.
func ByFromPackageEcosystem(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldFromPackageEcosystem, opts...).ToFunc()
}
// ByToPackageID orders the results by the to_package_id field.
func ByToPackageID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldToPackageID, opts...).ToFunc()
}
// ByToPackageName orders the results by the to_package_name field.
func ByToPackageName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldToPackageName, opts...).ToFunc()
}
// ByToPackageVersion orders the results by the to_package_version field.
func ByToPackageVersion(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldToPackageVersion, opts...).ToFunc()
}
// ByToPackageEcosystem orders the results by the to_package_ecosystem field.
func ByToPackageEcosystem(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldToPackageEcosystem, opts...).ToFunc()
}
// ByDependencyType orders the results by the dependency_type field.
func ByDependencyType(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDependencyType, opts...).ToFunc()
}
// ByVersionConstraint orders the results by the version_constraint field.
func ByVersionConstraint(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldVersionConstraint, opts...).ToFunc()
}
// ByDepth orders the results by the depth field.
func ByDepth(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldDepth, opts...).ToFunc()
}
// ByIsDirect orders the results by the is_direct field.
func ByIsDirect(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldIsDirect, opts...).ToFunc()
}
// ByIsRootEdge orders the results by the is_root_edge field.
func ByIsRootEdge(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldIsRootEdge, opts...).ToFunc()
}
// ByManifestID orders the results by the manifest_id field.
func ByManifestID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldManifestID, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,486 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/reportdependencygraph"
)
// ReportDependencyGraphCreate is the builder for creating a ReportDependencyGraph entity.
type ReportDependencyGraphCreate struct {
config
mutation *ReportDependencyGraphMutation
hooks []Hook
}
// SetFromPackageID sets the "from_package_id" field.
func (rdgc *ReportDependencyGraphCreate) SetFromPackageID(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetFromPackageID(s)
return rdgc
}
// SetFromPackageName sets the "from_package_name" field.
func (rdgc *ReportDependencyGraphCreate) SetFromPackageName(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetFromPackageName(s)
return rdgc
}
// SetFromPackageVersion sets the "from_package_version" field.
func (rdgc *ReportDependencyGraphCreate) SetFromPackageVersion(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetFromPackageVersion(s)
return rdgc
}
// SetFromPackageEcosystem sets the "from_package_ecosystem" field.
func (rdgc *ReportDependencyGraphCreate) SetFromPackageEcosystem(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetFromPackageEcosystem(s)
return rdgc
}
// SetToPackageID sets the "to_package_id" field.
func (rdgc *ReportDependencyGraphCreate) SetToPackageID(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetToPackageID(s)
return rdgc
}
// SetToPackageName sets the "to_package_name" field.
func (rdgc *ReportDependencyGraphCreate) SetToPackageName(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetToPackageName(s)
return rdgc
}
// SetToPackageVersion sets the "to_package_version" field.
func (rdgc *ReportDependencyGraphCreate) SetToPackageVersion(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetToPackageVersion(s)
return rdgc
}
// SetToPackageEcosystem sets the "to_package_ecosystem" field.
func (rdgc *ReportDependencyGraphCreate) SetToPackageEcosystem(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetToPackageEcosystem(s)
return rdgc
}
// SetDependencyType sets the "dependency_type" field.
func (rdgc *ReportDependencyGraphCreate) SetDependencyType(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetDependencyType(s)
return rdgc
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableDependencyType(s *string) *ReportDependencyGraphCreate {
if s != nil {
rdgc.SetDependencyType(*s)
}
return rdgc
}
// SetVersionConstraint sets the "version_constraint" field.
func (rdgc *ReportDependencyGraphCreate) SetVersionConstraint(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetVersionConstraint(s)
return rdgc
}
// SetNillableVersionConstraint sets the "version_constraint" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableVersionConstraint(s *string) *ReportDependencyGraphCreate {
if s != nil {
rdgc.SetVersionConstraint(*s)
}
return rdgc
}
// SetDepth sets the "depth" field.
func (rdgc *ReportDependencyGraphCreate) SetDepth(i int) *ReportDependencyGraphCreate {
rdgc.mutation.SetDepth(i)
return rdgc
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableDepth(i *int) *ReportDependencyGraphCreate {
if i != nil {
rdgc.SetDepth(*i)
}
return rdgc
}
// SetIsDirect sets the "is_direct" field.
func (rdgc *ReportDependencyGraphCreate) SetIsDirect(b bool) *ReportDependencyGraphCreate {
rdgc.mutation.SetIsDirect(b)
return rdgc
}
// SetNillableIsDirect sets the "is_direct" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableIsDirect(b *bool) *ReportDependencyGraphCreate {
if b != nil {
rdgc.SetIsDirect(*b)
}
return rdgc
}
// SetIsRootEdge sets the "is_root_edge" field.
func (rdgc *ReportDependencyGraphCreate) SetIsRootEdge(b bool) *ReportDependencyGraphCreate {
rdgc.mutation.SetIsRootEdge(b)
return rdgc
}
// SetNillableIsRootEdge sets the "is_root_edge" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableIsRootEdge(b *bool) *ReportDependencyGraphCreate {
if b != nil {
rdgc.SetIsRootEdge(*b)
}
return rdgc
}
// SetManifestID sets the "manifest_id" field.
func (rdgc *ReportDependencyGraphCreate) SetManifestID(s string) *ReportDependencyGraphCreate {
rdgc.mutation.SetManifestID(s)
return rdgc
}
// SetCreatedAt sets the "created_at" field.
func (rdgc *ReportDependencyGraphCreate) SetCreatedAt(t time.Time) *ReportDependencyGraphCreate {
rdgc.mutation.SetCreatedAt(t)
return rdgc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableCreatedAt(t *time.Time) *ReportDependencyGraphCreate {
if t != nil {
rdgc.SetCreatedAt(*t)
}
return rdgc
}
// SetUpdatedAt sets the "updated_at" field.
func (rdgc *ReportDependencyGraphCreate) SetUpdatedAt(t time.Time) *ReportDependencyGraphCreate {
rdgc.mutation.SetUpdatedAt(t)
return rdgc
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rdgc *ReportDependencyGraphCreate) SetNillableUpdatedAt(t *time.Time) *ReportDependencyGraphCreate {
if t != nil {
rdgc.SetUpdatedAt(*t)
}
return rdgc
}
// Mutation returns the ReportDependencyGraphMutation object of the builder.
func (rdgc *ReportDependencyGraphCreate) Mutation() *ReportDependencyGraphMutation {
return rdgc.mutation
}
// Save creates the ReportDependencyGraph in the database.
func (rdgc *ReportDependencyGraphCreate) Save(ctx context.Context) (*ReportDependencyGraph, error) {
rdgc.defaults()
return withHooks(ctx, rdgc.sqlSave, rdgc.mutation, rdgc.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (rdgc *ReportDependencyGraphCreate) SaveX(ctx context.Context) *ReportDependencyGraph {
v, err := rdgc.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rdgc *ReportDependencyGraphCreate) Exec(ctx context.Context) error {
_, err := rdgc.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdgc *ReportDependencyGraphCreate) ExecX(ctx context.Context) {
if err := rdgc.Exec(ctx); err != nil {
panic(err)
}
}
// defaults sets the default values of the builder before save.
func (rdgc *ReportDependencyGraphCreate) defaults() {
if _, ok := rdgc.mutation.Depth(); !ok {
v := reportdependencygraph.DefaultDepth
rdgc.mutation.SetDepth(v)
}
if _, ok := rdgc.mutation.IsDirect(); !ok {
v := reportdependencygraph.DefaultIsDirect
rdgc.mutation.SetIsDirect(v)
}
if _, ok := rdgc.mutation.IsRootEdge(); !ok {
v := reportdependencygraph.DefaultIsRootEdge
rdgc.mutation.SetIsRootEdge(v)
}
}
// check runs all checks and user-defined validators on the builder.
func (rdgc *ReportDependencyGraphCreate) check() error {
if _, ok := rdgc.mutation.FromPackageID(); !ok {
return &ValidationError{Name: "from_package_id", err: errors.New(`ent: missing required field "ReportDependencyGraph.from_package_id"`)}
}
if v, ok := rdgc.mutation.FromPackageID(); ok {
if err := reportdependencygraph.FromPackageIDValidator(v); err != nil {
return &ValidationError{Name: "from_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_id": %w`, err)}
}
}
if _, ok := rdgc.mutation.FromPackageName(); !ok {
return &ValidationError{Name: "from_package_name", err: errors.New(`ent: missing required field "ReportDependencyGraph.from_package_name"`)}
}
if v, ok := rdgc.mutation.FromPackageName(); ok {
if err := reportdependencygraph.FromPackageNameValidator(v); err != nil {
return &ValidationError{Name: "from_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_name": %w`, err)}
}
}
if _, ok := rdgc.mutation.FromPackageVersion(); !ok {
return &ValidationError{Name: "from_package_version", err: errors.New(`ent: missing required field "ReportDependencyGraph.from_package_version"`)}
}
if v, ok := rdgc.mutation.FromPackageVersion(); ok {
if err := reportdependencygraph.FromPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "from_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_version": %w`, err)}
}
}
if _, ok := rdgc.mutation.FromPackageEcosystem(); !ok {
return &ValidationError{Name: "from_package_ecosystem", err: errors.New(`ent: missing required field "ReportDependencyGraph.from_package_ecosystem"`)}
}
if v, ok := rdgc.mutation.FromPackageEcosystem(); ok {
if err := reportdependencygraph.FromPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "from_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_ecosystem": %w`, err)}
}
}
if _, ok := rdgc.mutation.ToPackageID(); !ok {
return &ValidationError{Name: "to_package_id", err: errors.New(`ent: missing required field "ReportDependencyGraph.to_package_id"`)}
}
if v, ok := rdgc.mutation.ToPackageID(); ok {
if err := reportdependencygraph.ToPackageIDValidator(v); err != nil {
return &ValidationError{Name: "to_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_id": %w`, err)}
}
}
if _, ok := rdgc.mutation.ToPackageName(); !ok {
return &ValidationError{Name: "to_package_name", err: errors.New(`ent: missing required field "ReportDependencyGraph.to_package_name"`)}
}
if v, ok := rdgc.mutation.ToPackageName(); ok {
if err := reportdependencygraph.ToPackageNameValidator(v); err != nil {
return &ValidationError{Name: "to_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_name": %w`, err)}
}
}
if _, ok := rdgc.mutation.ToPackageVersion(); !ok {
return &ValidationError{Name: "to_package_version", err: errors.New(`ent: missing required field "ReportDependencyGraph.to_package_version"`)}
}
if v, ok := rdgc.mutation.ToPackageVersion(); ok {
if err := reportdependencygraph.ToPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "to_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_version": %w`, err)}
}
}
if _, ok := rdgc.mutation.ToPackageEcosystem(); !ok {
return &ValidationError{Name: "to_package_ecosystem", err: errors.New(`ent: missing required field "ReportDependencyGraph.to_package_ecosystem"`)}
}
if v, ok := rdgc.mutation.ToPackageEcosystem(); ok {
if err := reportdependencygraph.ToPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "to_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_ecosystem": %w`, err)}
}
}
if _, ok := rdgc.mutation.Depth(); !ok {
return &ValidationError{Name: "depth", err: errors.New(`ent: missing required field "ReportDependencyGraph.depth"`)}
}
if _, ok := rdgc.mutation.IsDirect(); !ok {
return &ValidationError{Name: "is_direct", err: errors.New(`ent: missing required field "ReportDependencyGraph.is_direct"`)}
}
if _, ok := rdgc.mutation.IsRootEdge(); !ok {
return &ValidationError{Name: "is_root_edge", err: errors.New(`ent: missing required field "ReportDependencyGraph.is_root_edge"`)}
}
if _, ok := rdgc.mutation.ManifestID(); !ok {
return &ValidationError{Name: "manifest_id", err: errors.New(`ent: missing required field "ReportDependencyGraph.manifest_id"`)}
}
if v, ok := rdgc.mutation.ManifestID(); ok {
if err := reportdependencygraph.ManifestIDValidator(v); err != nil {
return &ValidationError{Name: "manifest_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.manifest_id": %w`, err)}
}
}
return nil
}
func (rdgc *ReportDependencyGraphCreate) sqlSave(ctx context.Context) (*ReportDependencyGraph, error) {
if err := rdgc.check(); err != nil {
return nil, err
}
_node, _spec := rdgc.createSpec()
if err := sqlgraph.CreateNode(ctx, rdgc.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
rdgc.mutation.id = &_node.ID
rdgc.mutation.done = true
return _node, nil
}
func (rdgc *ReportDependencyGraphCreate) createSpec() (*ReportDependencyGraph, *sqlgraph.CreateSpec) {
var (
_node = &ReportDependencyGraph{config: rdgc.config}
_spec = sqlgraph.NewCreateSpec(reportdependencygraph.Table, sqlgraph.NewFieldSpec(reportdependencygraph.FieldID, field.TypeInt))
)
if value, ok := rdgc.mutation.FromPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageID, field.TypeString, value)
_node.FromPackageID = value
}
if value, ok := rdgc.mutation.FromPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageName, field.TypeString, value)
_node.FromPackageName = value
}
if value, ok := rdgc.mutation.FromPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageVersion, field.TypeString, value)
_node.FromPackageVersion = value
}
if value, ok := rdgc.mutation.FromPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageEcosystem, field.TypeString, value)
_node.FromPackageEcosystem = value
}
if value, ok := rdgc.mutation.ToPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageID, field.TypeString, value)
_node.ToPackageID = value
}
if value, ok := rdgc.mutation.ToPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageName, field.TypeString, value)
_node.ToPackageName = value
}
if value, ok := rdgc.mutation.ToPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageVersion, field.TypeString, value)
_node.ToPackageVersion = value
}
if value, ok := rdgc.mutation.ToPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageEcosystem, field.TypeString, value)
_node.ToPackageEcosystem = value
}
if value, ok := rdgc.mutation.DependencyType(); ok {
_spec.SetField(reportdependencygraph.FieldDependencyType, field.TypeString, value)
_node.DependencyType = value
}
if value, ok := rdgc.mutation.VersionConstraint(); ok {
_spec.SetField(reportdependencygraph.FieldVersionConstraint, field.TypeString, value)
_node.VersionConstraint = value
}
if value, ok := rdgc.mutation.Depth(); ok {
_spec.SetField(reportdependencygraph.FieldDepth, field.TypeInt, value)
_node.Depth = value
}
if value, ok := rdgc.mutation.IsDirect(); ok {
_spec.SetField(reportdependencygraph.FieldIsDirect, field.TypeBool, value)
_node.IsDirect = value
}
if value, ok := rdgc.mutation.IsRootEdge(); ok {
_spec.SetField(reportdependencygraph.FieldIsRootEdge, field.TypeBool, value)
_node.IsRootEdge = value
}
if value, ok := rdgc.mutation.ManifestID(); ok {
_spec.SetField(reportdependencygraph.FieldManifestID, field.TypeString, value)
_node.ManifestID = value
}
if value, ok := rdgc.mutation.CreatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldCreatedAt, field.TypeTime, value)
_node.CreatedAt = value
}
if value, ok := rdgc.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldUpdatedAt, field.TypeTime, value)
_node.UpdatedAt = value
}
return _node, _spec
}
// ReportDependencyGraphCreateBulk is the builder for creating many ReportDependencyGraph entities in bulk.
type ReportDependencyGraphCreateBulk struct {
config
err error
builders []*ReportDependencyGraphCreate
}
// Save creates the ReportDependencyGraph entities in the database.
func (rdgcb *ReportDependencyGraphCreateBulk) Save(ctx context.Context) ([]*ReportDependencyGraph, error) {
if rdgcb.err != nil {
return nil, rdgcb.err
}
specs := make([]*sqlgraph.CreateSpec, len(rdgcb.builders))
nodes := make([]*ReportDependencyGraph, len(rdgcb.builders))
mutators := make([]Mutator, len(rdgcb.builders))
for i := range rdgcb.builders {
func(i int, root context.Context) {
builder := rdgcb.builders[i]
builder.defaults()
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ReportDependencyGraphMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, rdgcb.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, rdgcb.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, rdgcb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (rdgcb *ReportDependencyGraphCreateBulk) SaveX(ctx context.Context) []*ReportDependencyGraph {
v, err := rdgcb.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rdgcb *ReportDependencyGraphCreateBulk) Exec(ctx context.Context) error {
_, err := rdgcb.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdgcb *ReportDependencyGraphCreateBulk) ExecX(ctx context.Context) {
if err := rdgcb.Exec(ctx); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependencygraph"
)
// ReportDependencyGraphDelete is the builder for deleting a ReportDependencyGraph entity.
type ReportDependencyGraphDelete struct {
config
hooks []Hook
mutation *ReportDependencyGraphMutation
}
// Where appends a list predicates to the ReportDependencyGraphDelete builder.
func (rdgd *ReportDependencyGraphDelete) Where(ps ...predicate.ReportDependencyGraph) *ReportDependencyGraphDelete {
rdgd.mutation.Where(ps...)
return rdgd
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (rdgd *ReportDependencyGraphDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, rdgd.sqlExec, rdgd.mutation, rdgd.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (rdgd *ReportDependencyGraphDelete) ExecX(ctx context.Context) int {
n, err := rdgd.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (rdgd *ReportDependencyGraphDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(reportdependencygraph.Table, sqlgraph.NewFieldSpec(reportdependencygraph.FieldID, field.TypeInt))
if ps := rdgd.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, rdgd.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
rdgd.mutation.done = true
return affected, err
}
// ReportDependencyGraphDeleteOne is the builder for deleting a single ReportDependencyGraph entity.
type ReportDependencyGraphDeleteOne struct {
rdgd *ReportDependencyGraphDelete
}
// Where appends a list predicates to the ReportDependencyGraphDelete builder.
func (rdgdo *ReportDependencyGraphDeleteOne) Where(ps ...predicate.ReportDependencyGraph) *ReportDependencyGraphDeleteOne {
rdgdo.rdgd.mutation.Where(ps...)
return rdgdo
}
// Exec executes the deletion query.
func (rdgdo *ReportDependencyGraphDeleteOne) Exec(ctx context.Context) error {
n, err := rdgdo.rdgd.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{reportdependencygraph.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (rdgdo *ReportDependencyGraphDeleteOne) ExecX(ctx context.Context) {
if err := rdgdo.Exec(ctx); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,527 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependencygraph"
)
// ReportDependencyGraphQuery is the builder for querying ReportDependencyGraph entities.
type ReportDependencyGraphQuery struct {
config
ctx *QueryContext
order []reportdependencygraph.OrderOption
inters []Interceptor
predicates []predicate.ReportDependencyGraph
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the ReportDependencyGraphQuery builder.
func (rdgq *ReportDependencyGraphQuery) Where(ps ...predicate.ReportDependencyGraph) *ReportDependencyGraphQuery {
rdgq.predicates = append(rdgq.predicates, ps...)
return rdgq
}
// Limit the number of records to be returned by this query.
func (rdgq *ReportDependencyGraphQuery) Limit(limit int) *ReportDependencyGraphQuery {
rdgq.ctx.Limit = &limit
return rdgq
}
// Offset to start from.
func (rdgq *ReportDependencyGraphQuery) Offset(offset int) *ReportDependencyGraphQuery {
rdgq.ctx.Offset = &offset
return rdgq
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (rdgq *ReportDependencyGraphQuery) Unique(unique bool) *ReportDependencyGraphQuery {
rdgq.ctx.Unique = &unique
return rdgq
}
// Order specifies how the records should be ordered.
func (rdgq *ReportDependencyGraphQuery) Order(o ...reportdependencygraph.OrderOption) *ReportDependencyGraphQuery {
rdgq.order = append(rdgq.order, o...)
return rdgq
}
// First returns the first ReportDependencyGraph entity from the query.
// Returns a *NotFoundError when no ReportDependencyGraph was found.
func (rdgq *ReportDependencyGraphQuery) First(ctx context.Context) (*ReportDependencyGraph, error) {
nodes, err := rdgq.Limit(1).All(setContextOp(ctx, rdgq.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{reportdependencygraph.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) FirstX(ctx context.Context) *ReportDependencyGraph {
node, err := rdgq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first ReportDependencyGraph ID from the query.
// Returns a *NotFoundError when no ReportDependencyGraph ID was found.
func (rdgq *ReportDependencyGraphQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rdgq.Limit(1).IDs(setContextOp(ctx, rdgq.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{reportdependencygraph.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) FirstIDX(ctx context.Context) int {
id, err := rdgq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single ReportDependencyGraph entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one ReportDependencyGraph entity is found.
// Returns a *NotFoundError when no ReportDependencyGraph entities are found.
func (rdgq *ReportDependencyGraphQuery) Only(ctx context.Context) (*ReportDependencyGraph, error) {
nodes, err := rdgq.Limit(2).All(setContextOp(ctx, rdgq.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{reportdependencygraph.Label}
default:
return nil, &NotSingularError{reportdependencygraph.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) OnlyX(ctx context.Context) *ReportDependencyGraph {
node, err := rdgq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only ReportDependencyGraph ID in the query.
// Returns a *NotSingularError when more than one ReportDependencyGraph ID is found.
// Returns a *NotFoundError when no entities are found.
func (rdgq *ReportDependencyGraphQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rdgq.Limit(2).IDs(setContextOp(ctx, rdgq.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{reportdependencygraph.Label}
default:
err = &NotSingularError{reportdependencygraph.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) OnlyIDX(ctx context.Context) int {
id, err := rdgq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of ReportDependencyGraphs.
func (rdgq *ReportDependencyGraphQuery) All(ctx context.Context) ([]*ReportDependencyGraph, error) {
ctx = setContextOp(ctx, rdgq.ctx, ent.OpQueryAll)
if err := rdgq.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*ReportDependencyGraph, *ReportDependencyGraphQuery]()
return withInterceptors[[]*ReportDependencyGraph](ctx, rdgq, qr, rdgq.inters)
}
// AllX is like All, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) AllX(ctx context.Context) []*ReportDependencyGraph {
nodes, err := rdgq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of ReportDependencyGraph IDs.
func (rdgq *ReportDependencyGraphQuery) IDs(ctx context.Context) (ids []int, err error) {
if rdgq.ctx.Unique == nil && rdgq.path != nil {
rdgq.Unique(true)
}
ctx = setContextOp(ctx, rdgq.ctx, ent.OpQueryIDs)
if err = rdgq.Select(reportdependencygraph.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) IDsX(ctx context.Context) []int {
ids, err := rdgq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (rdgq *ReportDependencyGraphQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, rdgq.ctx, ent.OpQueryCount)
if err := rdgq.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, rdgq, querierCount[*ReportDependencyGraphQuery](), rdgq.inters)
}
// CountX is like Count, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) CountX(ctx context.Context) int {
count, err := rdgq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (rdgq *ReportDependencyGraphQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, rdgq.ctx, ent.OpQueryExist)
switch _, err := rdgq.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (rdgq *ReportDependencyGraphQuery) ExistX(ctx context.Context) bool {
exist, err := rdgq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the ReportDependencyGraphQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (rdgq *ReportDependencyGraphQuery) Clone() *ReportDependencyGraphQuery {
if rdgq == nil {
return nil
}
return &ReportDependencyGraphQuery{
config: rdgq.config,
ctx: rdgq.ctx.Clone(),
order: append([]reportdependencygraph.OrderOption{}, rdgq.order...),
inters: append([]Interceptor{}, rdgq.inters...),
predicates: append([]predicate.ReportDependencyGraph{}, rdgq.predicates...),
// clone intermediate query.
sql: rdgq.sql.Clone(),
path: rdgq.path,
}
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// FromPackageID string `json:"from_package_id,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.ReportDependencyGraph.Query().
// GroupBy(reportdependencygraph.FieldFromPackageID).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (rdgq *ReportDependencyGraphQuery) GroupBy(field string, fields ...string) *ReportDependencyGraphGroupBy {
rdgq.ctx.Fields = append([]string{field}, fields...)
grbuild := &ReportDependencyGraphGroupBy{build: rdgq}
grbuild.flds = &rdgq.ctx.Fields
grbuild.label = reportdependencygraph.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// FromPackageID string `json:"from_package_id,omitempty"`
// }
//
// client.ReportDependencyGraph.Query().
// Select(reportdependencygraph.FieldFromPackageID).
// Scan(ctx, &v)
func (rdgq *ReportDependencyGraphQuery) Select(fields ...string) *ReportDependencyGraphSelect {
rdgq.ctx.Fields = append(rdgq.ctx.Fields, fields...)
sbuild := &ReportDependencyGraphSelect{ReportDependencyGraphQuery: rdgq}
sbuild.label = reportdependencygraph.Label
sbuild.flds, sbuild.scan = &rdgq.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a ReportDependencyGraphSelect configured with the given aggregations.
func (rdgq *ReportDependencyGraphQuery) Aggregate(fns ...AggregateFunc) *ReportDependencyGraphSelect {
return rdgq.Select().Aggregate(fns...)
}
func (rdgq *ReportDependencyGraphQuery) prepareQuery(ctx context.Context) error {
for _, inter := range rdgq.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, rdgq); err != nil {
return err
}
}
}
for _, f := range rdgq.ctx.Fields {
if !reportdependencygraph.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if rdgq.path != nil {
prev, err := rdgq.path(ctx)
if err != nil {
return err
}
rdgq.sql = prev
}
return nil
}
func (rdgq *ReportDependencyGraphQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ReportDependencyGraph, error) {
var (
nodes = []*ReportDependencyGraph{}
_spec = rdgq.querySpec()
)
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*ReportDependencyGraph).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &ReportDependencyGraph{config: rdgq.config}
nodes = append(nodes, node)
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, rdgq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
return nodes, nil
}
func (rdgq *ReportDependencyGraphQuery) sqlCount(ctx context.Context) (int, error) {
_spec := rdgq.querySpec()
_spec.Node.Columns = rdgq.ctx.Fields
if len(rdgq.ctx.Fields) > 0 {
_spec.Unique = rdgq.ctx.Unique != nil && *rdgq.ctx.Unique
}
return sqlgraph.CountNodes(ctx, rdgq.driver, _spec)
}
func (rdgq *ReportDependencyGraphQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(reportdependencygraph.Table, reportdependencygraph.Columns, sqlgraph.NewFieldSpec(reportdependencygraph.FieldID, field.TypeInt))
_spec.From = rdgq.sql
if unique := rdgq.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if rdgq.path != nil {
_spec.Unique = true
}
if fields := rdgq.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportdependencygraph.FieldID)
for i := range fields {
if fields[i] != reportdependencygraph.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := rdgq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := rdgq.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := rdgq.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := rdgq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (rdgq *ReportDependencyGraphQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(rdgq.driver.Dialect())
t1 := builder.Table(reportdependencygraph.Table)
columns := rdgq.ctx.Fields
if len(columns) == 0 {
columns = reportdependencygraph.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if rdgq.sql != nil {
selector = rdgq.sql
selector.Select(selector.Columns(columns...)...)
}
if rdgq.ctx.Unique != nil && *rdgq.ctx.Unique {
selector.Distinct()
}
for _, p := range rdgq.predicates {
p(selector)
}
for _, p := range rdgq.order {
p(selector)
}
if offset := rdgq.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := rdgq.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ReportDependencyGraphGroupBy is the group-by builder for ReportDependencyGraph entities.
type ReportDependencyGraphGroupBy struct {
selector
build *ReportDependencyGraphQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (rdggb *ReportDependencyGraphGroupBy) Aggregate(fns ...AggregateFunc) *ReportDependencyGraphGroupBy {
rdggb.fns = append(rdggb.fns, fns...)
return rdggb
}
// Scan applies the selector query and scans the result into the given value.
func (rdggb *ReportDependencyGraphGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rdggb.build.ctx, ent.OpQueryGroupBy)
if err := rdggb.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportDependencyGraphQuery, *ReportDependencyGraphGroupBy](ctx, rdggb.build, rdggb, rdggb.build.inters, v)
}
func (rdggb *ReportDependencyGraphGroupBy) sqlScan(ctx context.Context, root *ReportDependencyGraphQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(rdggb.fns))
for _, fn := range rdggb.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*rdggb.flds)+len(rdggb.fns))
for _, f := range *rdggb.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*rdggb.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rdggb.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// ReportDependencyGraphSelect is the builder for selecting fields of ReportDependencyGraph entities.
type ReportDependencyGraphSelect struct {
*ReportDependencyGraphQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (rdgs *ReportDependencyGraphSelect) Aggregate(fns ...AggregateFunc) *ReportDependencyGraphSelect {
rdgs.fns = append(rdgs.fns, fns...)
return rdgs
}
// Scan applies the selector query and scans the result into the given value.
func (rdgs *ReportDependencyGraphSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rdgs.ctx, ent.OpQuerySelect)
if err := rdgs.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportDependencyGraphQuery, *ReportDependencyGraphSelect](ctx, rdgs.ReportDependencyGraphQuery, rdgs, rdgs.inters, v)
}
func (rdgs *ReportDependencyGraphSelect) sqlScan(ctx context.Context, root *ReportDependencyGraphQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(rdgs.fns))
for _, fn := range rdgs.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*rdgs.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rdgs.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}

View File

@ -0,0 +1,918 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportdependencygraph"
)
// ReportDependencyGraphUpdate is the builder for updating ReportDependencyGraph entities.
type ReportDependencyGraphUpdate struct {
config
hooks []Hook
mutation *ReportDependencyGraphMutation
}
// Where appends a list predicates to the ReportDependencyGraphUpdate builder.
func (rdgu *ReportDependencyGraphUpdate) Where(ps ...predicate.ReportDependencyGraph) *ReportDependencyGraphUpdate {
rdgu.mutation.Where(ps...)
return rdgu
}
// SetFromPackageID sets the "from_package_id" field.
func (rdgu *ReportDependencyGraphUpdate) SetFromPackageID(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetFromPackageID(s)
return rdgu
}
// SetNillableFromPackageID sets the "from_package_id" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableFromPackageID(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetFromPackageID(*s)
}
return rdgu
}
// SetFromPackageName sets the "from_package_name" field.
func (rdgu *ReportDependencyGraphUpdate) SetFromPackageName(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetFromPackageName(s)
return rdgu
}
// SetNillableFromPackageName sets the "from_package_name" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableFromPackageName(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetFromPackageName(*s)
}
return rdgu
}
// SetFromPackageVersion sets the "from_package_version" field.
func (rdgu *ReportDependencyGraphUpdate) SetFromPackageVersion(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetFromPackageVersion(s)
return rdgu
}
// SetNillableFromPackageVersion sets the "from_package_version" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableFromPackageVersion(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetFromPackageVersion(*s)
}
return rdgu
}
// SetFromPackageEcosystem sets the "from_package_ecosystem" field.
func (rdgu *ReportDependencyGraphUpdate) SetFromPackageEcosystem(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetFromPackageEcosystem(s)
return rdgu
}
// SetNillableFromPackageEcosystem sets the "from_package_ecosystem" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableFromPackageEcosystem(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetFromPackageEcosystem(*s)
}
return rdgu
}
// SetToPackageID sets the "to_package_id" field.
func (rdgu *ReportDependencyGraphUpdate) SetToPackageID(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetToPackageID(s)
return rdgu
}
// SetNillableToPackageID sets the "to_package_id" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableToPackageID(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetToPackageID(*s)
}
return rdgu
}
// SetToPackageName sets the "to_package_name" field.
func (rdgu *ReportDependencyGraphUpdate) SetToPackageName(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetToPackageName(s)
return rdgu
}
// SetNillableToPackageName sets the "to_package_name" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableToPackageName(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetToPackageName(*s)
}
return rdgu
}
// SetToPackageVersion sets the "to_package_version" field.
func (rdgu *ReportDependencyGraphUpdate) SetToPackageVersion(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetToPackageVersion(s)
return rdgu
}
// SetNillableToPackageVersion sets the "to_package_version" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableToPackageVersion(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetToPackageVersion(*s)
}
return rdgu
}
// SetToPackageEcosystem sets the "to_package_ecosystem" field.
func (rdgu *ReportDependencyGraphUpdate) SetToPackageEcosystem(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetToPackageEcosystem(s)
return rdgu
}
// SetNillableToPackageEcosystem sets the "to_package_ecosystem" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableToPackageEcosystem(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetToPackageEcosystem(*s)
}
return rdgu
}
// SetDependencyType sets the "dependency_type" field.
func (rdgu *ReportDependencyGraphUpdate) SetDependencyType(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetDependencyType(s)
return rdgu
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableDependencyType(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetDependencyType(*s)
}
return rdgu
}
// ClearDependencyType clears the value of the "dependency_type" field.
func (rdgu *ReportDependencyGraphUpdate) ClearDependencyType() *ReportDependencyGraphUpdate {
rdgu.mutation.ClearDependencyType()
return rdgu
}
// SetVersionConstraint sets the "version_constraint" field.
func (rdgu *ReportDependencyGraphUpdate) SetVersionConstraint(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetVersionConstraint(s)
return rdgu
}
// SetNillableVersionConstraint sets the "version_constraint" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableVersionConstraint(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetVersionConstraint(*s)
}
return rdgu
}
// ClearVersionConstraint clears the value of the "version_constraint" field.
func (rdgu *ReportDependencyGraphUpdate) ClearVersionConstraint() *ReportDependencyGraphUpdate {
rdgu.mutation.ClearVersionConstraint()
return rdgu
}
// SetDepth sets the "depth" field.
func (rdgu *ReportDependencyGraphUpdate) SetDepth(i int) *ReportDependencyGraphUpdate {
rdgu.mutation.ResetDepth()
rdgu.mutation.SetDepth(i)
return rdgu
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableDepth(i *int) *ReportDependencyGraphUpdate {
if i != nil {
rdgu.SetDepth(*i)
}
return rdgu
}
// AddDepth adds i to the "depth" field.
func (rdgu *ReportDependencyGraphUpdate) AddDepth(i int) *ReportDependencyGraphUpdate {
rdgu.mutation.AddDepth(i)
return rdgu
}
// SetIsDirect sets the "is_direct" field.
func (rdgu *ReportDependencyGraphUpdate) SetIsDirect(b bool) *ReportDependencyGraphUpdate {
rdgu.mutation.SetIsDirect(b)
return rdgu
}
// SetNillableIsDirect sets the "is_direct" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableIsDirect(b *bool) *ReportDependencyGraphUpdate {
if b != nil {
rdgu.SetIsDirect(*b)
}
return rdgu
}
// SetIsRootEdge sets the "is_root_edge" field.
func (rdgu *ReportDependencyGraphUpdate) SetIsRootEdge(b bool) *ReportDependencyGraphUpdate {
rdgu.mutation.SetIsRootEdge(b)
return rdgu
}
// SetNillableIsRootEdge sets the "is_root_edge" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableIsRootEdge(b *bool) *ReportDependencyGraphUpdate {
if b != nil {
rdgu.SetIsRootEdge(*b)
}
return rdgu
}
// SetManifestID sets the "manifest_id" field.
func (rdgu *ReportDependencyGraphUpdate) SetManifestID(s string) *ReportDependencyGraphUpdate {
rdgu.mutation.SetManifestID(s)
return rdgu
}
// SetNillableManifestID sets the "manifest_id" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableManifestID(s *string) *ReportDependencyGraphUpdate {
if s != nil {
rdgu.SetManifestID(*s)
}
return rdgu
}
// SetCreatedAt sets the "created_at" field.
func (rdgu *ReportDependencyGraphUpdate) SetCreatedAt(t time.Time) *ReportDependencyGraphUpdate {
rdgu.mutation.SetCreatedAt(t)
return rdgu
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableCreatedAt(t *time.Time) *ReportDependencyGraphUpdate {
if t != nil {
rdgu.SetCreatedAt(*t)
}
return rdgu
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rdgu *ReportDependencyGraphUpdate) ClearCreatedAt() *ReportDependencyGraphUpdate {
rdgu.mutation.ClearCreatedAt()
return rdgu
}
// SetUpdatedAt sets the "updated_at" field.
func (rdgu *ReportDependencyGraphUpdate) SetUpdatedAt(t time.Time) *ReportDependencyGraphUpdate {
rdgu.mutation.SetUpdatedAt(t)
return rdgu
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rdgu *ReportDependencyGraphUpdate) SetNillableUpdatedAt(t *time.Time) *ReportDependencyGraphUpdate {
if t != nil {
rdgu.SetUpdatedAt(*t)
}
return rdgu
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rdgu *ReportDependencyGraphUpdate) ClearUpdatedAt() *ReportDependencyGraphUpdate {
rdgu.mutation.ClearUpdatedAt()
return rdgu
}
// Mutation returns the ReportDependencyGraphMutation object of the builder.
func (rdgu *ReportDependencyGraphUpdate) Mutation() *ReportDependencyGraphMutation {
return rdgu.mutation
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (rdgu *ReportDependencyGraphUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, rdgu.sqlSave, rdgu.mutation, rdgu.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rdgu *ReportDependencyGraphUpdate) SaveX(ctx context.Context) int {
affected, err := rdgu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (rdgu *ReportDependencyGraphUpdate) Exec(ctx context.Context) error {
_, err := rdgu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdgu *ReportDependencyGraphUpdate) ExecX(ctx context.Context) {
if err := rdgu.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rdgu *ReportDependencyGraphUpdate) check() error {
if v, ok := rdgu.mutation.FromPackageID(); ok {
if err := reportdependencygraph.FromPackageIDValidator(v); err != nil {
return &ValidationError{Name: "from_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_id": %w`, err)}
}
}
if v, ok := rdgu.mutation.FromPackageName(); ok {
if err := reportdependencygraph.FromPackageNameValidator(v); err != nil {
return &ValidationError{Name: "from_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_name": %w`, err)}
}
}
if v, ok := rdgu.mutation.FromPackageVersion(); ok {
if err := reportdependencygraph.FromPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "from_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_version": %w`, err)}
}
}
if v, ok := rdgu.mutation.FromPackageEcosystem(); ok {
if err := reportdependencygraph.FromPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "from_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_ecosystem": %w`, err)}
}
}
if v, ok := rdgu.mutation.ToPackageID(); ok {
if err := reportdependencygraph.ToPackageIDValidator(v); err != nil {
return &ValidationError{Name: "to_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_id": %w`, err)}
}
}
if v, ok := rdgu.mutation.ToPackageName(); ok {
if err := reportdependencygraph.ToPackageNameValidator(v); err != nil {
return &ValidationError{Name: "to_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_name": %w`, err)}
}
}
if v, ok := rdgu.mutation.ToPackageVersion(); ok {
if err := reportdependencygraph.ToPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "to_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_version": %w`, err)}
}
}
if v, ok := rdgu.mutation.ToPackageEcosystem(); ok {
if err := reportdependencygraph.ToPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "to_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_ecosystem": %w`, err)}
}
}
if v, ok := rdgu.mutation.ManifestID(); ok {
if err := reportdependencygraph.ManifestIDValidator(v); err != nil {
return &ValidationError{Name: "manifest_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.manifest_id": %w`, err)}
}
}
return nil
}
func (rdgu *ReportDependencyGraphUpdate) sqlSave(ctx context.Context) (n int, err error) {
if err := rdgu.check(); err != nil {
return n, err
}
_spec := sqlgraph.NewUpdateSpec(reportdependencygraph.Table, reportdependencygraph.Columns, sqlgraph.NewFieldSpec(reportdependencygraph.FieldID, field.TypeInt))
if ps := rdgu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rdgu.mutation.FromPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageID, field.TypeString, value)
}
if value, ok := rdgu.mutation.FromPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageName, field.TypeString, value)
}
if value, ok := rdgu.mutation.FromPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageVersion, field.TypeString, value)
}
if value, ok := rdgu.mutation.FromPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageEcosystem, field.TypeString, value)
}
if value, ok := rdgu.mutation.ToPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageID, field.TypeString, value)
}
if value, ok := rdgu.mutation.ToPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageName, field.TypeString, value)
}
if value, ok := rdgu.mutation.ToPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageVersion, field.TypeString, value)
}
if value, ok := rdgu.mutation.ToPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageEcosystem, field.TypeString, value)
}
if value, ok := rdgu.mutation.DependencyType(); ok {
_spec.SetField(reportdependencygraph.FieldDependencyType, field.TypeString, value)
}
if rdgu.mutation.DependencyTypeCleared() {
_spec.ClearField(reportdependencygraph.FieldDependencyType, field.TypeString)
}
if value, ok := rdgu.mutation.VersionConstraint(); ok {
_spec.SetField(reportdependencygraph.FieldVersionConstraint, field.TypeString, value)
}
if rdgu.mutation.VersionConstraintCleared() {
_spec.ClearField(reportdependencygraph.FieldVersionConstraint, field.TypeString)
}
if value, ok := rdgu.mutation.Depth(); ok {
_spec.SetField(reportdependencygraph.FieldDepth, field.TypeInt, value)
}
if value, ok := rdgu.mutation.AddedDepth(); ok {
_spec.AddField(reportdependencygraph.FieldDepth, field.TypeInt, value)
}
if value, ok := rdgu.mutation.IsDirect(); ok {
_spec.SetField(reportdependencygraph.FieldIsDirect, field.TypeBool, value)
}
if value, ok := rdgu.mutation.IsRootEdge(); ok {
_spec.SetField(reportdependencygraph.FieldIsRootEdge, field.TypeBool, value)
}
if value, ok := rdgu.mutation.ManifestID(); ok {
_spec.SetField(reportdependencygraph.FieldManifestID, field.TypeString, value)
}
if value, ok := rdgu.mutation.CreatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldCreatedAt, field.TypeTime, value)
}
if rdgu.mutation.CreatedAtCleared() {
_spec.ClearField(reportdependencygraph.FieldCreatedAt, field.TypeTime)
}
if value, ok := rdgu.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldUpdatedAt, field.TypeTime, value)
}
if rdgu.mutation.UpdatedAtCleared() {
_spec.ClearField(reportdependencygraph.FieldUpdatedAt, field.TypeTime)
}
if n, err = sqlgraph.UpdateNodes(ctx, rdgu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportdependencygraph.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
rdgu.mutation.done = true
return n, nil
}
// ReportDependencyGraphUpdateOne is the builder for updating a single ReportDependencyGraph entity.
type ReportDependencyGraphUpdateOne struct {
config
fields []string
hooks []Hook
mutation *ReportDependencyGraphMutation
}
// SetFromPackageID sets the "from_package_id" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetFromPackageID(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetFromPackageID(s)
return rdguo
}
// SetNillableFromPackageID sets the "from_package_id" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableFromPackageID(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetFromPackageID(*s)
}
return rdguo
}
// SetFromPackageName sets the "from_package_name" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetFromPackageName(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetFromPackageName(s)
return rdguo
}
// SetNillableFromPackageName sets the "from_package_name" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableFromPackageName(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetFromPackageName(*s)
}
return rdguo
}
// SetFromPackageVersion sets the "from_package_version" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetFromPackageVersion(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetFromPackageVersion(s)
return rdguo
}
// SetNillableFromPackageVersion sets the "from_package_version" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableFromPackageVersion(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetFromPackageVersion(*s)
}
return rdguo
}
// SetFromPackageEcosystem sets the "from_package_ecosystem" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetFromPackageEcosystem(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetFromPackageEcosystem(s)
return rdguo
}
// SetNillableFromPackageEcosystem sets the "from_package_ecosystem" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableFromPackageEcosystem(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetFromPackageEcosystem(*s)
}
return rdguo
}
// SetToPackageID sets the "to_package_id" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetToPackageID(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetToPackageID(s)
return rdguo
}
// SetNillableToPackageID sets the "to_package_id" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableToPackageID(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetToPackageID(*s)
}
return rdguo
}
// SetToPackageName sets the "to_package_name" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetToPackageName(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetToPackageName(s)
return rdguo
}
// SetNillableToPackageName sets the "to_package_name" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableToPackageName(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetToPackageName(*s)
}
return rdguo
}
// SetToPackageVersion sets the "to_package_version" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetToPackageVersion(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetToPackageVersion(s)
return rdguo
}
// SetNillableToPackageVersion sets the "to_package_version" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableToPackageVersion(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetToPackageVersion(*s)
}
return rdguo
}
// SetToPackageEcosystem sets the "to_package_ecosystem" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetToPackageEcosystem(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetToPackageEcosystem(s)
return rdguo
}
// SetNillableToPackageEcosystem sets the "to_package_ecosystem" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableToPackageEcosystem(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetToPackageEcosystem(*s)
}
return rdguo
}
// SetDependencyType sets the "dependency_type" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetDependencyType(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetDependencyType(s)
return rdguo
}
// SetNillableDependencyType sets the "dependency_type" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableDependencyType(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetDependencyType(*s)
}
return rdguo
}
// ClearDependencyType clears the value of the "dependency_type" field.
func (rdguo *ReportDependencyGraphUpdateOne) ClearDependencyType() *ReportDependencyGraphUpdateOne {
rdguo.mutation.ClearDependencyType()
return rdguo
}
// SetVersionConstraint sets the "version_constraint" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetVersionConstraint(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetVersionConstraint(s)
return rdguo
}
// SetNillableVersionConstraint sets the "version_constraint" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableVersionConstraint(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetVersionConstraint(*s)
}
return rdguo
}
// ClearVersionConstraint clears the value of the "version_constraint" field.
func (rdguo *ReportDependencyGraphUpdateOne) ClearVersionConstraint() *ReportDependencyGraphUpdateOne {
rdguo.mutation.ClearVersionConstraint()
return rdguo
}
// SetDepth sets the "depth" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetDepth(i int) *ReportDependencyGraphUpdateOne {
rdguo.mutation.ResetDepth()
rdguo.mutation.SetDepth(i)
return rdguo
}
// SetNillableDepth sets the "depth" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableDepth(i *int) *ReportDependencyGraphUpdateOne {
if i != nil {
rdguo.SetDepth(*i)
}
return rdguo
}
// AddDepth adds i to the "depth" field.
func (rdguo *ReportDependencyGraphUpdateOne) AddDepth(i int) *ReportDependencyGraphUpdateOne {
rdguo.mutation.AddDepth(i)
return rdguo
}
// SetIsDirect sets the "is_direct" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetIsDirect(b bool) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetIsDirect(b)
return rdguo
}
// SetNillableIsDirect sets the "is_direct" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableIsDirect(b *bool) *ReportDependencyGraphUpdateOne {
if b != nil {
rdguo.SetIsDirect(*b)
}
return rdguo
}
// SetIsRootEdge sets the "is_root_edge" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetIsRootEdge(b bool) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetIsRootEdge(b)
return rdguo
}
// SetNillableIsRootEdge sets the "is_root_edge" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableIsRootEdge(b *bool) *ReportDependencyGraphUpdateOne {
if b != nil {
rdguo.SetIsRootEdge(*b)
}
return rdguo
}
// SetManifestID sets the "manifest_id" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetManifestID(s string) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetManifestID(s)
return rdguo
}
// SetNillableManifestID sets the "manifest_id" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableManifestID(s *string) *ReportDependencyGraphUpdateOne {
if s != nil {
rdguo.SetManifestID(*s)
}
return rdguo
}
// SetCreatedAt sets the "created_at" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetCreatedAt(t time.Time) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetCreatedAt(t)
return rdguo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableCreatedAt(t *time.Time) *ReportDependencyGraphUpdateOne {
if t != nil {
rdguo.SetCreatedAt(*t)
}
return rdguo
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rdguo *ReportDependencyGraphUpdateOne) ClearCreatedAt() *ReportDependencyGraphUpdateOne {
rdguo.mutation.ClearCreatedAt()
return rdguo
}
// SetUpdatedAt sets the "updated_at" field.
func (rdguo *ReportDependencyGraphUpdateOne) SetUpdatedAt(t time.Time) *ReportDependencyGraphUpdateOne {
rdguo.mutation.SetUpdatedAt(t)
return rdguo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rdguo *ReportDependencyGraphUpdateOne) SetNillableUpdatedAt(t *time.Time) *ReportDependencyGraphUpdateOne {
if t != nil {
rdguo.SetUpdatedAt(*t)
}
return rdguo
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rdguo *ReportDependencyGraphUpdateOne) ClearUpdatedAt() *ReportDependencyGraphUpdateOne {
rdguo.mutation.ClearUpdatedAt()
return rdguo
}
// Mutation returns the ReportDependencyGraphMutation object of the builder.
func (rdguo *ReportDependencyGraphUpdateOne) Mutation() *ReportDependencyGraphMutation {
return rdguo.mutation
}
// Where appends a list predicates to the ReportDependencyGraphUpdate builder.
func (rdguo *ReportDependencyGraphUpdateOne) Where(ps ...predicate.ReportDependencyGraph) *ReportDependencyGraphUpdateOne {
rdguo.mutation.Where(ps...)
return rdguo
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (rdguo *ReportDependencyGraphUpdateOne) Select(field string, fields ...string) *ReportDependencyGraphUpdateOne {
rdguo.fields = append([]string{field}, fields...)
return rdguo
}
// Save executes the query and returns the updated ReportDependencyGraph entity.
func (rdguo *ReportDependencyGraphUpdateOne) Save(ctx context.Context) (*ReportDependencyGraph, error) {
return withHooks(ctx, rdguo.sqlSave, rdguo.mutation, rdguo.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rdguo *ReportDependencyGraphUpdateOne) SaveX(ctx context.Context) *ReportDependencyGraph {
node, err := rdguo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (rdguo *ReportDependencyGraphUpdateOne) Exec(ctx context.Context) error {
_, err := rdguo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rdguo *ReportDependencyGraphUpdateOne) ExecX(ctx context.Context) {
if err := rdguo.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rdguo *ReportDependencyGraphUpdateOne) check() error {
if v, ok := rdguo.mutation.FromPackageID(); ok {
if err := reportdependencygraph.FromPackageIDValidator(v); err != nil {
return &ValidationError{Name: "from_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_id": %w`, err)}
}
}
if v, ok := rdguo.mutation.FromPackageName(); ok {
if err := reportdependencygraph.FromPackageNameValidator(v); err != nil {
return &ValidationError{Name: "from_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_name": %w`, err)}
}
}
if v, ok := rdguo.mutation.FromPackageVersion(); ok {
if err := reportdependencygraph.FromPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "from_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_version": %w`, err)}
}
}
if v, ok := rdguo.mutation.FromPackageEcosystem(); ok {
if err := reportdependencygraph.FromPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "from_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.from_package_ecosystem": %w`, err)}
}
}
if v, ok := rdguo.mutation.ToPackageID(); ok {
if err := reportdependencygraph.ToPackageIDValidator(v); err != nil {
return &ValidationError{Name: "to_package_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_id": %w`, err)}
}
}
if v, ok := rdguo.mutation.ToPackageName(); ok {
if err := reportdependencygraph.ToPackageNameValidator(v); err != nil {
return &ValidationError{Name: "to_package_name", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_name": %w`, err)}
}
}
if v, ok := rdguo.mutation.ToPackageVersion(); ok {
if err := reportdependencygraph.ToPackageVersionValidator(v); err != nil {
return &ValidationError{Name: "to_package_version", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_version": %w`, err)}
}
}
if v, ok := rdguo.mutation.ToPackageEcosystem(); ok {
if err := reportdependencygraph.ToPackageEcosystemValidator(v); err != nil {
return &ValidationError{Name: "to_package_ecosystem", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.to_package_ecosystem": %w`, err)}
}
}
if v, ok := rdguo.mutation.ManifestID(); ok {
if err := reportdependencygraph.ManifestIDValidator(v); err != nil {
return &ValidationError{Name: "manifest_id", err: fmt.Errorf(`ent: validator failed for field "ReportDependencyGraph.manifest_id": %w`, err)}
}
}
return nil
}
func (rdguo *ReportDependencyGraphUpdateOne) sqlSave(ctx context.Context) (_node *ReportDependencyGraph, err error) {
if err := rdguo.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(reportdependencygraph.Table, reportdependencygraph.Columns, sqlgraph.NewFieldSpec(reportdependencygraph.FieldID, field.TypeInt))
id, ok := rdguo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ReportDependencyGraph.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := rdguo.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportdependencygraph.FieldID)
for _, f := range fields {
if !reportdependencygraph.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != reportdependencygraph.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := rdguo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rdguo.mutation.FromPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageID, field.TypeString, value)
}
if value, ok := rdguo.mutation.FromPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageName, field.TypeString, value)
}
if value, ok := rdguo.mutation.FromPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageVersion, field.TypeString, value)
}
if value, ok := rdguo.mutation.FromPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldFromPackageEcosystem, field.TypeString, value)
}
if value, ok := rdguo.mutation.ToPackageID(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageID, field.TypeString, value)
}
if value, ok := rdguo.mutation.ToPackageName(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageName, field.TypeString, value)
}
if value, ok := rdguo.mutation.ToPackageVersion(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageVersion, field.TypeString, value)
}
if value, ok := rdguo.mutation.ToPackageEcosystem(); ok {
_spec.SetField(reportdependencygraph.FieldToPackageEcosystem, field.TypeString, value)
}
if value, ok := rdguo.mutation.DependencyType(); ok {
_spec.SetField(reportdependencygraph.FieldDependencyType, field.TypeString, value)
}
if rdguo.mutation.DependencyTypeCleared() {
_spec.ClearField(reportdependencygraph.FieldDependencyType, field.TypeString)
}
if value, ok := rdguo.mutation.VersionConstraint(); ok {
_spec.SetField(reportdependencygraph.FieldVersionConstraint, field.TypeString, value)
}
if rdguo.mutation.VersionConstraintCleared() {
_spec.ClearField(reportdependencygraph.FieldVersionConstraint, field.TypeString)
}
if value, ok := rdguo.mutation.Depth(); ok {
_spec.SetField(reportdependencygraph.FieldDepth, field.TypeInt, value)
}
if value, ok := rdguo.mutation.AddedDepth(); ok {
_spec.AddField(reportdependencygraph.FieldDepth, field.TypeInt, value)
}
if value, ok := rdguo.mutation.IsDirect(); ok {
_spec.SetField(reportdependencygraph.FieldIsDirect, field.TypeBool, value)
}
if value, ok := rdguo.mutation.IsRootEdge(); ok {
_spec.SetField(reportdependencygraph.FieldIsRootEdge, field.TypeBool, value)
}
if value, ok := rdguo.mutation.ManifestID(); ok {
_spec.SetField(reportdependencygraph.FieldManifestID, field.TypeString, value)
}
if value, ok := rdguo.mutation.CreatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldCreatedAt, field.TypeTime, value)
}
if rdguo.mutation.CreatedAtCleared() {
_spec.ClearField(reportdependencygraph.FieldCreatedAt, field.TypeTime)
}
if value, ok := rdguo.mutation.UpdatedAt(); ok {
_spec.SetField(reportdependencygraph.FieldUpdatedAt, field.TypeTime, value)
}
if rdguo.mutation.UpdatedAtCleared() {
_spec.ClearField(reportdependencygraph.FieldUpdatedAt, field.TypeTime)
}
_node = &ReportDependencyGraph{config: rdguo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, rdguo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportdependencygraph.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
rdguo.mutation.done = true
return _node, nil
}

200
ent/reportlicense.go Normal file
View File

@ -0,0 +1,200 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/safedep/vet/ent/reportlicense"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportLicense is the model entity for the ReportLicense schema.
type ReportLicense struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// LicenseID holds the value of the "license_id" field.
LicenseID string `json:"license_id,omitempty"`
// Name holds the value of the "name" field.
Name string `json:"name,omitempty"`
// SpdxID holds the value of the "spdx_id" field.
SpdxID string `json:"spdx_id,omitempty"`
// URL holds the value of the "url" field.
URL string `json:"url,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the ReportLicenseQuery when eager-loading is set.
Edges ReportLicenseEdges `json:"edges"`
report_package_licenses *int
selectValues sql.SelectValues
}
// ReportLicenseEdges holds the relations/edges for other nodes in the graph.
type ReportLicenseEdges struct {
// Package holds the value of the package edge.
Package *ReportPackage `json:"package,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// PackageOrErr returns the Package value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ReportLicenseEdges) PackageOrErr() (*ReportPackage, error) {
if e.Package != nil {
return e.Package, nil
} else if e.loadedTypes[0] {
return nil, &NotFoundError{label: reportpackage.Label}
}
return nil, &NotLoadedError{edge: "package"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*ReportLicense) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case reportlicense.FieldID:
values[i] = new(sql.NullInt64)
case reportlicense.FieldLicenseID, reportlicense.FieldName, reportlicense.FieldSpdxID, reportlicense.FieldURL:
values[i] = new(sql.NullString)
case reportlicense.FieldCreatedAt, reportlicense.FieldUpdatedAt:
values[i] = new(sql.NullTime)
case reportlicense.ForeignKeys[0]: // report_package_licenses
values[i] = new(sql.NullInt64)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the ReportLicense fields.
func (rl *ReportLicense) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case reportlicense.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
rl.ID = int(value.Int64)
case reportlicense.FieldLicenseID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field license_id", values[i])
} else if value.Valid {
rl.LicenseID = value.String
}
case reportlicense.FieldName:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field name", values[i])
} else if value.Valid {
rl.Name = value.String
}
case reportlicense.FieldSpdxID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field spdx_id", values[i])
} else if value.Valid {
rl.SpdxID = value.String
}
case reportlicense.FieldURL:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field url", values[i])
} else if value.Valid {
rl.URL = value.String
}
case reportlicense.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
rl.CreatedAt = value.Time
}
case reportlicense.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
rl.UpdatedAt = value.Time
}
case reportlicense.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field report_package_licenses", value)
} else if value.Valid {
rl.report_package_licenses = new(int)
*rl.report_package_licenses = int(value.Int64)
}
default:
rl.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the ReportLicense.
// This includes values selected through modifiers, order, etc.
func (rl *ReportLicense) Value(name string) (ent.Value, error) {
return rl.selectValues.Get(name)
}
// QueryPackage queries the "package" edge of the ReportLicense entity.
func (rl *ReportLicense) QueryPackage() *ReportPackageQuery {
return NewReportLicenseClient(rl.config).QueryPackage(rl)
}
// Update returns a builder for updating this ReportLicense.
// Note that you need to call ReportLicense.Unwrap() before calling this method if this ReportLicense
// was returned from a transaction, and the transaction was committed or rolled back.
func (rl *ReportLicense) Update() *ReportLicenseUpdateOne {
return NewReportLicenseClient(rl.config).UpdateOne(rl)
}
// Unwrap unwraps the ReportLicense entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (rl *ReportLicense) Unwrap() *ReportLicense {
_tx, ok := rl.config.driver.(*txDriver)
if !ok {
panic("ent: ReportLicense is not a transactional entity")
}
rl.config.driver = _tx.drv
return rl
}
// String implements the fmt.Stringer.
func (rl *ReportLicense) String() string {
var builder strings.Builder
builder.WriteString("ReportLicense(")
builder.WriteString(fmt.Sprintf("id=%v, ", rl.ID))
builder.WriteString("license_id=")
builder.WriteString(rl.LicenseID)
builder.WriteString(", ")
builder.WriteString("name=")
builder.WriteString(rl.Name)
builder.WriteString(", ")
builder.WriteString("spdx_id=")
builder.WriteString(rl.SpdxID)
builder.WriteString(", ")
builder.WriteString("url=")
builder.WriteString(rl.URL)
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(rl.CreatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(rl.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// ReportLicenses is a parsable slice of ReportLicense.
type ReportLicenses []*ReportLicense

View File

@ -0,0 +1,127 @@
// Code generated by ent, DO NOT EDIT.
package reportlicense
import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
const (
// Label holds the string label denoting the reportlicense type in the database.
Label = "report_license"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldLicenseID holds the string denoting the license_id field in the database.
FieldLicenseID = "license_id"
// FieldName holds the string denoting the name field in the database.
FieldName = "name"
// FieldSpdxID holds the string denoting the spdx_id field in the database.
FieldSpdxID = "spdx_id"
// FieldURL holds the string denoting the url field in the database.
FieldURL = "url"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgePackage holds the string denoting the package edge name in mutations.
EdgePackage = "package"
// Table holds the table name of the reportlicense in the database.
Table = "report_licenses"
// PackageTable is the table that holds the package relation/edge.
PackageTable = "report_licenses"
// PackageInverseTable is the table name for the ReportPackage entity.
// It exists in this package in order to avoid circular dependency with the "reportpackage" package.
PackageInverseTable = "report_packages"
// PackageColumn is the table column denoting the package relation/edge.
PackageColumn = "report_package_licenses"
)
// Columns holds all SQL columns for reportlicense fields.
var Columns = []string{
FieldID,
FieldLicenseID,
FieldName,
FieldSpdxID,
FieldURL,
FieldCreatedAt,
FieldUpdatedAt,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "report_licenses"
// table and are not defined as standalone fields in the schema.
var ForeignKeys = []string{
"report_package_licenses",
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
for i := range ForeignKeys {
if column == ForeignKeys[i] {
return true
}
}
return false
}
var (
// LicenseIDValidator is a validator for the "license_id" field. It is called by the builders before save.
LicenseIDValidator func(string) error
)
// OrderOption defines the ordering options for the ReportLicense queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByLicenseID orders the results by the license_id field.
func ByLicenseID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldLicenseID, opts...).ToFunc()
}
// ByName orders the results by the name field.
func ByName(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldName, opts...).ToFunc()
}
// BySpdxID orders the results by the spdx_id field.
func BySpdxID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldSpdxID, opts...).ToFunc()
}
// ByURL orders the results by the url field.
func ByURL(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldURL, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByPackageField orders the results by package field.
func ByPackageField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newPackageStep(), sql.OrderByField(field, opts...))
}
}
func newPackageStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PackageInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PackageTable, PackageColumn),
)
}

514
ent/reportlicense/where.go Normal file
View File

@ -0,0 +1,514 @@
// Code generated by ent, DO NOT EDIT.
package reportlicense
import (
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"github.com/safedep/vet/ent/predicate"
)
// ID filters vertices based on their ID field.
func ID(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldID, id))
}
// IDEQ applies the EQ predicate on the ID field.
func IDEQ(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldID, id))
}
// IDNEQ applies the NEQ predicate on the ID field.
func IDNEQ(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldID, id))
}
// IDIn applies the In predicate on the ID field.
func IDIn(ids ...int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldID, ids...))
}
// IDNotIn applies the NotIn predicate on the ID field.
func IDNotIn(ids ...int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldID, ids...))
}
// IDGT applies the GT predicate on the ID field.
func IDGT(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldID, id))
}
// IDGTE applies the GTE predicate on the ID field.
func IDGTE(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldID, id))
}
// IDLT applies the LT predicate on the ID field.
func IDLT(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldID, id))
}
// IDLTE applies the LTE predicate on the ID field.
func IDLTE(id int) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldID, id))
}
// LicenseID applies equality check predicate on the "license_id" field. It's identical to LicenseIDEQ.
func LicenseID(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldLicenseID, v))
}
// Name applies equality check predicate on the "name" field. It's identical to NameEQ.
func Name(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldName, v))
}
// SpdxID applies equality check predicate on the "spdx_id" field. It's identical to SpdxIDEQ.
func SpdxID(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldSpdxID, v))
}
// URL applies equality check predicate on the "url" field. It's identical to URLEQ.
func URL(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldURL, v))
}
// CreatedAt applies equality check predicate on the "created_at" field. It's identical to CreatedAtEQ.
func CreatedAt(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldCreatedAt, v))
}
// UpdatedAt applies equality check predicate on the "updated_at" field. It's identical to UpdatedAtEQ.
func UpdatedAt(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldUpdatedAt, v))
}
// LicenseIDEQ applies the EQ predicate on the "license_id" field.
func LicenseIDEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldLicenseID, v))
}
// LicenseIDNEQ applies the NEQ predicate on the "license_id" field.
func LicenseIDNEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldLicenseID, v))
}
// LicenseIDIn applies the In predicate on the "license_id" field.
func LicenseIDIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldLicenseID, vs...))
}
// LicenseIDNotIn applies the NotIn predicate on the "license_id" field.
func LicenseIDNotIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldLicenseID, vs...))
}
// LicenseIDGT applies the GT predicate on the "license_id" field.
func LicenseIDGT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldLicenseID, v))
}
// LicenseIDGTE applies the GTE predicate on the "license_id" field.
func LicenseIDGTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldLicenseID, v))
}
// LicenseIDLT applies the LT predicate on the "license_id" field.
func LicenseIDLT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldLicenseID, v))
}
// LicenseIDLTE applies the LTE predicate on the "license_id" field.
func LicenseIDLTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldLicenseID, v))
}
// LicenseIDContains applies the Contains predicate on the "license_id" field.
func LicenseIDContains(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContains(FieldLicenseID, v))
}
// LicenseIDHasPrefix applies the HasPrefix predicate on the "license_id" field.
func LicenseIDHasPrefix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasPrefix(FieldLicenseID, v))
}
// LicenseIDHasSuffix applies the HasSuffix predicate on the "license_id" field.
func LicenseIDHasSuffix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasSuffix(FieldLicenseID, v))
}
// LicenseIDEqualFold applies the EqualFold predicate on the "license_id" field.
func LicenseIDEqualFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEqualFold(FieldLicenseID, v))
}
// LicenseIDContainsFold applies the ContainsFold predicate on the "license_id" field.
func LicenseIDContainsFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContainsFold(FieldLicenseID, v))
}
// NameEQ applies the EQ predicate on the "name" field.
func NameEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldName, v))
}
// NameNEQ applies the NEQ predicate on the "name" field.
func NameNEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldName, v))
}
// NameIn applies the In predicate on the "name" field.
func NameIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldName, vs...))
}
// NameNotIn applies the NotIn predicate on the "name" field.
func NameNotIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldName, vs...))
}
// NameGT applies the GT predicate on the "name" field.
func NameGT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldName, v))
}
// NameGTE applies the GTE predicate on the "name" field.
func NameGTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldName, v))
}
// NameLT applies the LT predicate on the "name" field.
func NameLT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldName, v))
}
// NameLTE applies the LTE predicate on the "name" field.
func NameLTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldName, v))
}
// NameContains applies the Contains predicate on the "name" field.
func NameContains(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContains(FieldName, v))
}
// NameHasPrefix applies the HasPrefix predicate on the "name" field.
func NameHasPrefix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasPrefix(FieldName, v))
}
// NameHasSuffix applies the HasSuffix predicate on the "name" field.
func NameHasSuffix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasSuffix(FieldName, v))
}
// NameIsNil applies the IsNil predicate on the "name" field.
func NameIsNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIsNull(FieldName))
}
// NameNotNil applies the NotNil predicate on the "name" field.
func NameNotNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotNull(FieldName))
}
// NameEqualFold applies the EqualFold predicate on the "name" field.
func NameEqualFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEqualFold(FieldName, v))
}
// NameContainsFold applies the ContainsFold predicate on the "name" field.
func NameContainsFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContainsFold(FieldName, v))
}
// SpdxIDEQ applies the EQ predicate on the "spdx_id" field.
func SpdxIDEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldSpdxID, v))
}
// SpdxIDNEQ applies the NEQ predicate on the "spdx_id" field.
func SpdxIDNEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldSpdxID, v))
}
// SpdxIDIn applies the In predicate on the "spdx_id" field.
func SpdxIDIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldSpdxID, vs...))
}
// SpdxIDNotIn applies the NotIn predicate on the "spdx_id" field.
func SpdxIDNotIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldSpdxID, vs...))
}
// SpdxIDGT applies the GT predicate on the "spdx_id" field.
func SpdxIDGT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldSpdxID, v))
}
// SpdxIDGTE applies the GTE predicate on the "spdx_id" field.
func SpdxIDGTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldSpdxID, v))
}
// SpdxIDLT applies the LT predicate on the "spdx_id" field.
func SpdxIDLT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldSpdxID, v))
}
// SpdxIDLTE applies the LTE predicate on the "spdx_id" field.
func SpdxIDLTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldSpdxID, v))
}
// SpdxIDContains applies the Contains predicate on the "spdx_id" field.
func SpdxIDContains(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContains(FieldSpdxID, v))
}
// SpdxIDHasPrefix applies the HasPrefix predicate on the "spdx_id" field.
func SpdxIDHasPrefix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasPrefix(FieldSpdxID, v))
}
// SpdxIDHasSuffix applies the HasSuffix predicate on the "spdx_id" field.
func SpdxIDHasSuffix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasSuffix(FieldSpdxID, v))
}
// SpdxIDIsNil applies the IsNil predicate on the "spdx_id" field.
func SpdxIDIsNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIsNull(FieldSpdxID))
}
// SpdxIDNotNil applies the NotNil predicate on the "spdx_id" field.
func SpdxIDNotNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotNull(FieldSpdxID))
}
// SpdxIDEqualFold applies the EqualFold predicate on the "spdx_id" field.
func SpdxIDEqualFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEqualFold(FieldSpdxID, v))
}
// SpdxIDContainsFold applies the ContainsFold predicate on the "spdx_id" field.
func SpdxIDContainsFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContainsFold(FieldSpdxID, v))
}
// URLEQ applies the EQ predicate on the "url" field.
func URLEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldURL, v))
}
// URLNEQ applies the NEQ predicate on the "url" field.
func URLNEQ(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldURL, v))
}
// URLIn applies the In predicate on the "url" field.
func URLIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldURL, vs...))
}
// URLNotIn applies the NotIn predicate on the "url" field.
func URLNotIn(vs ...string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldURL, vs...))
}
// URLGT applies the GT predicate on the "url" field.
func URLGT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldURL, v))
}
// URLGTE applies the GTE predicate on the "url" field.
func URLGTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldURL, v))
}
// URLLT applies the LT predicate on the "url" field.
func URLLT(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldURL, v))
}
// URLLTE applies the LTE predicate on the "url" field.
func URLLTE(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldURL, v))
}
// URLContains applies the Contains predicate on the "url" field.
func URLContains(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContains(FieldURL, v))
}
// URLHasPrefix applies the HasPrefix predicate on the "url" field.
func URLHasPrefix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasPrefix(FieldURL, v))
}
// URLHasSuffix applies the HasSuffix predicate on the "url" field.
func URLHasSuffix(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldHasSuffix(FieldURL, v))
}
// URLIsNil applies the IsNil predicate on the "url" field.
func URLIsNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIsNull(FieldURL))
}
// URLNotNil applies the NotNil predicate on the "url" field.
func URLNotNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotNull(FieldURL))
}
// URLEqualFold applies the EqualFold predicate on the "url" field.
func URLEqualFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEqualFold(FieldURL, v))
}
// URLContainsFold applies the ContainsFold predicate on the "url" field.
func URLContainsFold(v string) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldContainsFold(FieldURL, v))
}
// CreatedAtEQ applies the EQ predicate on the "created_at" field.
func CreatedAtEQ(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldCreatedAt, v))
}
// CreatedAtNEQ applies the NEQ predicate on the "created_at" field.
func CreatedAtNEQ(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldCreatedAt, v))
}
// CreatedAtIn applies the In predicate on the "created_at" field.
func CreatedAtIn(vs ...time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldCreatedAt, vs...))
}
// CreatedAtNotIn applies the NotIn predicate on the "created_at" field.
func CreatedAtNotIn(vs ...time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldCreatedAt, vs...))
}
// CreatedAtGT applies the GT predicate on the "created_at" field.
func CreatedAtGT(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldCreatedAt, v))
}
// CreatedAtGTE applies the GTE predicate on the "created_at" field.
func CreatedAtGTE(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldCreatedAt, v))
}
// CreatedAtLT applies the LT predicate on the "created_at" field.
func CreatedAtLT(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldCreatedAt, v))
}
// CreatedAtLTE applies the LTE predicate on the "created_at" field.
func CreatedAtLTE(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldCreatedAt, v))
}
// CreatedAtIsNil applies the IsNil predicate on the "created_at" field.
func CreatedAtIsNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIsNull(FieldCreatedAt))
}
// CreatedAtNotNil applies the NotNil predicate on the "created_at" field.
func CreatedAtNotNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotNull(FieldCreatedAt))
}
// UpdatedAtEQ applies the EQ predicate on the "updated_at" field.
func UpdatedAtEQ(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldEQ(FieldUpdatedAt, v))
}
// UpdatedAtNEQ applies the NEQ predicate on the "updated_at" field.
func UpdatedAtNEQ(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNEQ(FieldUpdatedAt, v))
}
// UpdatedAtIn applies the In predicate on the "updated_at" field.
func UpdatedAtIn(vs ...time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIn(FieldUpdatedAt, vs...))
}
// UpdatedAtNotIn applies the NotIn predicate on the "updated_at" field.
func UpdatedAtNotIn(vs ...time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotIn(FieldUpdatedAt, vs...))
}
// UpdatedAtGT applies the GT predicate on the "updated_at" field.
func UpdatedAtGT(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGT(FieldUpdatedAt, v))
}
// UpdatedAtGTE applies the GTE predicate on the "updated_at" field.
func UpdatedAtGTE(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldGTE(FieldUpdatedAt, v))
}
// UpdatedAtLT applies the LT predicate on the "updated_at" field.
func UpdatedAtLT(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLT(FieldUpdatedAt, v))
}
// UpdatedAtLTE applies the LTE predicate on the "updated_at" field.
func UpdatedAtLTE(v time.Time) predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldLTE(FieldUpdatedAt, v))
}
// UpdatedAtIsNil applies the IsNil predicate on the "updated_at" field.
func UpdatedAtIsNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldIsNull(FieldUpdatedAt))
}
// UpdatedAtNotNil applies the NotNil predicate on the "updated_at" field.
func UpdatedAtNotNil() predicate.ReportLicense {
return predicate.ReportLicense(sql.FieldNotNull(FieldUpdatedAt))
}
// HasPackage applies the HasEdge predicate on the "package" edge.
func HasPackage() predicate.ReportLicense {
return predicate.ReportLicense(func(s *sql.Selector) {
step := sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, PackageTable, PackageColumn),
)
sqlgraph.HasNeighbors(s, step)
})
}
// HasPackageWith applies the HasEdge predicate on the "package" edge with a given conditions (other predicates).
func HasPackageWith(preds ...predicate.ReportPackage) predicate.ReportLicense {
return predicate.ReportLicense(func(s *sql.Selector) {
step := newPackageStep()
sqlgraph.HasNeighborsWith(s, step, func(s *sql.Selector) {
for _, p := range preds {
p(s)
}
})
})
}
// And groups predicates with the AND operator between them.
func And(predicates ...predicate.ReportLicense) predicate.ReportLicense {
return predicate.ReportLicense(sql.AndPredicates(predicates...))
}
// Or groups predicates with the OR operator between them.
func Or(predicates ...predicate.ReportLicense) predicate.ReportLicense {
return predicate.ReportLicense(sql.OrPredicates(predicates...))
}
// Not applies the not operator on the given predicate.
func Not(p predicate.ReportLicense) predicate.ReportLicense {
return predicate.ReportLicense(sql.NotPredicates(p))
}

316
ent/reportlicense_create.go Normal file
View File

@ -0,0 +1,316 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/reportlicense"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportLicenseCreate is the builder for creating a ReportLicense entity.
type ReportLicenseCreate struct {
config
mutation *ReportLicenseMutation
hooks []Hook
}
// SetLicenseID sets the "license_id" field.
func (rlc *ReportLicenseCreate) SetLicenseID(s string) *ReportLicenseCreate {
rlc.mutation.SetLicenseID(s)
return rlc
}
// SetName sets the "name" field.
func (rlc *ReportLicenseCreate) SetName(s string) *ReportLicenseCreate {
rlc.mutation.SetName(s)
return rlc
}
// SetNillableName sets the "name" field if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillableName(s *string) *ReportLicenseCreate {
if s != nil {
rlc.SetName(*s)
}
return rlc
}
// SetSpdxID sets the "spdx_id" field.
func (rlc *ReportLicenseCreate) SetSpdxID(s string) *ReportLicenseCreate {
rlc.mutation.SetSpdxID(s)
return rlc
}
// SetNillableSpdxID sets the "spdx_id" field if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillableSpdxID(s *string) *ReportLicenseCreate {
if s != nil {
rlc.SetSpdxID(*s)
}
return rlc
}
// SetURL sets the "url" field.
func (rlc *ReportLicenseCreate) SetURL(s string) *ReportLicenseCreate {
rlc.mutation.SetURL(s)
return rlc
}
// SetNillableURL sets the "url" field if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillableURL(s *string) *ReportLicenseCreate {
if s != nil {
rlc.SetURL(*s)
}
return rlc
}
// SetCreatedAt sets the "created_at" field.
func (rlc *ReportLicenseCreate) SetCreatedAt(t time.Time) *ReportLicenseCreate {
rlc.mutation.SetCreatedAt(t)
return rlc
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillableCreatedAt(t *time.Time) *ReportLicenseCreate {
if t != nil {
rlc.SetCreatedAt(*t)
}
return rlc
}
// SetUpdatedAt sets the "updated_at" field.
func (rlc *ReportLicenseCreate) SetUpdatedAt(t time.Time) *ReportLicenseCreate {
rlc.mutation.SetUpdatedAt(t)
return rlc
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillableUpdatedAt(t *time.Time) *ReportLicenseCreate {
if t != nil {
rlc.SetUpdatedAt(*t)
}
return rlc
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rlc *ReportLicenseCreate) SetPackageID(id int) *ReportLicenseCreate {
rlc.mutation.SetPackageID(id)
return rlc
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rlc *ReportLicenseCreate) SetNillablePackageID(id *int) *ReportLicenseCreate {
if id != nil {
rlc = rlc.SetPackageID(*id)
}
return rlc
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rlc *ReportLicenseCreate) SetPackage(r *ReportPackage) *ReportLicenseCreate {
return rlc.SetPackageID(r.ID)
}
// Mutation returns the ReportLicenseMutation object of the builder.
func (rlc *ReportLicenseCreate) Mutation() *ReportLicenseMutation {
return rlc.mutation
}
// Save creates the ReportLicense in the database.
func (rlc *ReportLicenseCreate) Save(ctx context.Context) (*ReportLicense, error) {
return withHooks(ctx, rlc.sqlSave, rlc.mutation, rlc.hooks)
}
// SaveX calls Save and panics if Save returns an error.
func (rlc *ReportLicenseCreate) SaveX(ctx context.Context) *ReportLicense {
v, err := rlc.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rlc *ReportLicenseCreate) Exec(ctx context.Context) error {
_, err := rlc.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rlc *ReportLicenseCreate) ExecX(ctx context.Context) {
if err := rlc.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rlc *ReportLicenseCreate) check() error {
if _, ok := rlc.mutation.LicenseID(); !ok {
return &ValidationError{Name: "license_id", err: errors.New(`ent: missing required field "ReportLicense.license_id"`)}
}
if v, ok := rlc.mutation.LicenseID(); ok {
if err := reportlicense.LicenseIDValidator(v); err != nil {
return &ValidationError{Name: "license_id", err: fmt.Errorf(`ent: validator failed for field "ReportLicense.license_id": %w`, err)}
}
}
return nil
}
func (rlc *ReportLicenseCreate) sqlSave(ctx context.Context) (*ReportLicense, error) {
if err := rlc.check(); err != nil {
return nil, err
}
_node, _spec := rlc.createSpec()
if err := sqlgraph.CreateNode(ctx, rlc.driver, _spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
id := _spec.ID.Value.(int64)
_node.ID = int(id)
rlc.mutation.id = &_node.ID
rlc.mutation.done = true
return _node, nil
}
func (rlc *ReportLicenseCreate) createSpec() (*ReportLicense, *sqlgraph.CreateSpec) {
var (
_node = &ReportLicense{config: rlc.config}
_spec = sqlgraph.NewCreateSpec(reportlicense.Table, sqlgraph.NewFieldSpec(reportlicense.FieldID, field.TypeInt))
)
if value, ok := rlc.mutation.LicenseID(); ok {
_spec.SetField(reportlicense.FieldLicenseID, field.TypeString, value)
_node.LicenseID = value
}
if value, ok := rlc.mutation.Name(); ok {
_spec.SetField(reportlicense.FieldName, field.TypeString, value)
_node.Name = value
}
if value, ok := rlc.mutation.SpdxID(); ok {
_spec.SetField(reportlicense.FieldSpdxID, field.TypeString, value)
_node.SpdxID = value
}
if value, ok := rlc.mutation.URL(); ok {
_spec.SetField(reportlicense.FieldURL, field.TypeString, value)
_node.URL = value
}
if value, ok := rlc.mutation.CreatedAt(); ok {
_spec.SetField(reportlicense.FieldCreatedAt, field.TypeTime, value)
_node.CreatedAt = value
}
if value, ok := rlc.mutation.UpdatedAt(); ok {
_spec.SetField(reportlicense.FieldUpdatedAt, field.TypeTime, value)
_node.UpdatedAt = value
}
if nodes := rlc.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportlicense.PackageTable,
Columns: []string{reportlicense.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_node.report_package_licenses = &nodes[0]
_spec.Edges = append(_spec.Edges, edge)
}
return _node, _spec
}
// ReportLicenseCreateBulk is the builder for creating many ReportLicense entities in bulk.
type ReportLicenseCreateBulk struct {
config
err error
builders []*ReportLicenseCreate
}
// Save creates the ReportLicense entities in the database.
func (rlcb *ReportLicenseCreateBulk) Save(ctx context.Context) ([]*ReportLicense, error) {
if rlcb.err != nil {
return nil, rlcb.err
}
specs := make([]*sqlgraph.CreateSpec, len(rlcb.builders))
nodes := make([]*ReportLicense, len(rlcb.builders))
mutators := make([]Mutator, len(rlcb.builders))
for i := range rlcb.builders {
func(i int, root context.Context) {
builder := rlcb.builders[i]
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
mutation, ok := m.(*ReportLicenseMutation)
if !ok {
return nil, fmt.Errorf("unexpected mutation type %T", m)
}
if err := builder.check(); err != nil {
return nil, err
}
builder.mutation = mutation
var err error
nodes[i], specs[i] = builder.createSpec()
if i < len(mutators)-1 {
_, err = mutators[i+1].Mutate(root, rlcb.builders[i+1].mutation)
} else {
spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
// Invoke the actual operation on the latest mutation in the chain.
if err = sqlgraph.BatchCreate(ctx, rlcb.driver, spec); err != nil {
if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
}
}
if err != nil {
return nil, err
}
mutation.id = &nodes[i].ID
if specs[i].ID.Value != nil {
id := specs[i].ID.Value.(int64)
nodes[i].ID = int(id)
}
mutation.done = true
return nodes[i], nil
})
for i := len(builder.hooks) - 1; i >= 0; i-- {
mut = builder.hooks[i](mut)
}
mutators[i] = mut
}(i, ctx)
}
if len(mutators) > 0 {
if _, err := mutators[0].Mutate(ctx, rlcb.builders[0].mutation); err != nil {
return nil, err
}
}
return nodes, nil
}
// SaveX is like Save, but panics if an error occurs.
func (rlcb *ReportLicenseCreateBulk) SaveX(ctx context.Context) []*ReportLicense {
v, err := rlcb.Save(ctx)
if err != nil {
panic(err)
}
return v
}
// Exec executes the query.
func (rlcb *ReportLicenseCreateBulk) Exec(ctx context.Context) error {
_, err := rlcb.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rlcb *ReportLicenseCreateBulk) ExecX(ctx context.Context) {
if err := rlcb.Exec(ctx); err != nil {
panic(err)
}
}

View File

@ -0,0 +1,88 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportlicense"
)
// ReportLicenseDelete is the builder for deleting a ReportLicense entity.
type ReportLicenseDelete struct {
config
hooks []Hook
mutation *ReportLicenseMutation
}
// Where appends a list predicates to the ReportLicenseDelete builder.
func (rld *ReportLicenseDelete) Where(ps ...predicate.ReportLicense) *ReportLicenseDelete {
rld.mutation.Where(ps...)
return rld
}
// Exec executes the deletion query and returns how many vertices were deleted.
func (rld *ReportLicenseDelete) Exec(ctx context.Context) (int, error) {
return withHooks(ctx, rld.sqlExec, rld.mutation, rld.hooks)
}
// ExecX is like Exec, but panics if an error occurs.
func (rld *ReportLicenseDelete) ExecX(ctx context.Context) int {
n, err := rld.Exec(ctx)
if err != nil {
panic(err)
}
return n
}
func (rld *ReportLicenseDelete) sqlExec(ctx context.Context) (int, error) {
_spec := sqlgraph.NewDeleteSpec(reportlicense.Table, sqlgraph.NewFieldSpec(reportlicense.FieldID, field.TypeInt))
if ps := rld.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
affected, err := sqlgraph.DeleteNodes(ctx, rld.driver, _spec)
if err != nil && sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
rld.mutation.done = true
return affected, err
}
// ReportLicenseDeleteOne is the builder for deleting a single ReportLicense entity.
type ReportLicenseDeleteOne struct {
rld *ReportLicenseDelete
}
// Where appends a list predicates to the ReportLicenseDelete builder.
func (rldo *ReportLicenseDeleteOne) Where(ps ...predicate.ReportLicense) *ReportLicenseDeleteOne {
rldo.rld.mutation.Where(ps...)
return rldo
}
// Exec executes the deletion query.
func (rldo *ReportLicenseDeleteOne) Exec(ctx context.Context) error {
n, err := rldo.rld.Exec(ctx)
switch {
case err != nil:
return err
case n == 0:
return &NotFoundError{reportlicense.Label}
default:
return nil
}
}
// ExecX is like Exec, but panics if an error occurs.
func (rldo *ReportLicenseDeleteOne) ExecX(ctx context.Context) {
if err := rldo.Exec(ctx); err != nil {
panic(err)
}
}

614
ent/reportlicense_query.go Normal file
View File

@ -0,0 +1,614 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"fmt"
"math"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportlicense"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportLicenseQuery is the builder for querying ReportLicense entities.
type ReportLicenseQuery struct {
config
ctx *QueryContext
order []reportlicense.OrderOption
inters []Interceptor
predicates []predicate.ReportLicense
withPackage *ReportPackageQuery
withFKs bool
// intermediate query (i.e. traversal path).
sql *sql.Selector
path func(context.Context) (*sql.Selector, error)
}
// Where adds a new predicate for the ReportLicenseQuery builder.
func (rlq *ReportLicenseQuery) Where(ps ...predicate.ReportLicense) *ReportLicenseQuery {
rlq.predicates = append(rlq.predicates, ps...)
return rlq
}
// Limit the number of records to be returned by this query.
func (rlq *ReportLicenseQuery) Limit(limit int) *ReportLicenseQuery {
rlq.ctx.Limit = &limit
return rlq
}
// Offset to start from.
func (rlq *ReportLicenseQuery) Offset(offset int) *ReportLicenseQuery {
rlq.ctx.Offset = &offset
return rlq
}
// Unique configures the query builder to filter duplicate records on query.
// By default, unique is set to true, and can be disabled using this method.
func (rlq *ReportLicenseQuery) Unique(unique bool) *ReportLicenseQuery {
rlq.ctx.Unique = &unique
return rlq
}
// Order specifies how the records should be ordered.
func (rlq *ReportLicenseQuery) Order(o ...reportlicense.OrderOption) *ReportLicenseQuery {
rlq.order = append(rlq.order, o...)
return rlq
}
// QueryPackage chains the current query on the "package" edge.
func (rlq *ReportLicenseQuery) QueryPackage() *ReportPackageQuery {
query := (&ReportPackageClient{config: rlq.config}).Query()
query.path = func(ctx context.Context) (fromU *sql.Selector, err error) {
if err := rlq.prepareQuery(ctx); err != nil {
return nil, err
}
selector := rlq.sqlQuery(ctx)
if err := selector.Err(); err != nil {
return nil, err
}
step := sqlgraph.NewStep(
sqlgraph.From(reportlicense.Table, reportlicense.FieldID, selector),
sqlgraph.To(reportpackage.Table, reportpackage.FieldID),
sqlgraph.Edge(sqlgraph.M2O, true, reportlicense.PackageTable, reportlicense.PackageColumn),
)
fromU = sqlgraph.SetNeighbors(rlq.driver.Dialect(), step)
return fromU, nil
}
return query
}
// First returns the first ReportLicense entity from the query.
// Returns a *NotFoundError when no ReportLicense was found.
func (rlq *ReportLicenseQuery) First(ctx context.Context) (*ReportLicense, error) {
nodes, err := rlq.Limit(1).All(setContextOp(ctx, rlq.ctx, ent.OpQueryFirst))
if err != nil {
return nil, err
}
if len(nodes) == 0 {
return nil, &NotFoundError{reportlicense.Label}
}
return nodes[0], nil
}
// FirstX is like First, but panics if an error occurs.
func (rlq *ReportLicenseQuery) FirstX(ctx context.Context) *ReportLicense {
node, err := rlq.First(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return node
}
// FirstID returns the first ReportLicense ID from the query.
// Returns a *NotFoundError when no ReportLicense ID was found.
func (rlq *ReportLicenseQuery) FirstID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rlq.Limit(1).IDs(setContextOp(ctx, rlq.ctx, ent.OpQueryFirstID)); err != nil {
return
}
if len(ids) == 0 {
err = &NotFoundError{reportlicense.Label}
return
}
return ids[0], nil
}
// FirstIDX is like FirstID, but panics if an error occurs.
func (rlq *ReportLicenseQuery) FirstIDX(ctx context.Context) int {
id, err := rlq.FirstID(ctx)
if err != nil && !IsNotFound(err) {
panic(err)
}
return id
}
// Only returns a single ReportLicense entity found by the query, ensuring it only returns one.
// Returns a *NotSingularError when more than one ReportLicense entity is found.
// Returns a *NotFoundError when no ReportLicense entities are found.
func (rlq *ReportLicenseQuery) Only(ctx context.Context) (*ReportLicense, error) {
nodes, err := rlq.Limit(2).All(setContextOp(ctx, rlq.ctx, ent.OpQueryOnly))
if err != nil {
return nil, err
}
switch len(nodes) {
case 1:
return nodes[0], nil
case 0:
return nil, &NotFoundError{reportlicense.Label}
default:
return nil, &NotSingularError{reportlicense.Label}
}
}
// OnlyX is like Only, but panics if an error occurs.
func (rlq *ReportLicenseQuery) OnlyX(ctx context.Context) *ReportLicense {
node, err := rlq.Only(ctx)
if err != nil {
panic(err)
}
return node
}
// OnlyID is like Only, but returns the only ReportLicense ID in the query.
// Returns a *NotSingularError when more than one ReportLicense ID is found.
// Returns a *NotFoundError when no entities are found.
func (rlq *ReportLicenseQuery) OnlyID(ctx context.Context) (id int, err error) {
var ids []int
if ids, err = rlq.Limit(2).IDs(setContextOp(ctx, rlq.ctx, ent.OpQueryOnlyID)); err != nil {
return
}
switch len(ids) {
case 1:
id = ids[0]
case 0:
err = &NotFoundError{reportlicense.Label}
default:
err = &NotSingularError{reportlicense.Label}
}
return
}
// OnlyIDX is like OnlyID, but panics if an error occurs.
func (rlq *ReportLicenseQuery) OnlyIDX(ctx context.Context) int {
id, err := rlq.OnlyID(ctx)
if err != nil {
panic(err)
}
return id
}
// All executes the query and returns a list of ReportLicenses.
func (rlq *ReportLicenseQuery) All(ctx context.Context) ([]*ReportLicense, error) {
ctx = setContextOp(ctx, rlq.ctx, ent.OpQueryAll)
if err := rlq.prepareQuery(ctx); err != nil {
return nil, err
}
qr := querierAll[[]*ReportLicense, *ReportLicenseQuery]()
return withInterceptors[[]*ReportLicense](ctx, rlq, qr, rlq.inters)
}
// AllX is like All, but panics if an error occurs.
func (rlq *ReportLicenseQuery) AllX(ctx context.Context) []*ReportLicense {
nodes, err := rlq.All(ctx)
if err != nil {
panic(err)
}
return nodes
}
// IDs executes the query and returns a list of ReportLicense IDs.
func (rlq *ReportLicenseQuery) IDs(ctx context.Context) (ids []int, err error) {
if rlq.ctx.Unique == nil && rlq.path != nil {
rlq.Unique(true)
}
ctx = setContextOp(ctx, rlq.ctx, ent.OpQueryIDs)
if err = rlq.Select(reportlicense.FieldID).Scan(ctx, &ids); err != nil {
return nil, err
}
return ids, nil
}
// IDsX is like IDs, but panics if an error occurs.
func (rlq *ReportLicenseQuery) IDsX(ctx context.Context) []int {
ids, err := rlq.IDs(ctx)
if err != nil {
panic(err)
}
return ids
}
// Count returns the count of the given query.
func (rlq *ReportLicenseQuery) Count(ctx context.Context) (int, error) {
ctx = setContextOp(ctx, rlq.ctx, ent.OpQueryCount)
if err := rlq.prepareQuery(ctx); err != nil {
return 0, err
}
return withInterceptors[int](ctx, rlq, querierCount[*ReportLicenseQuery](), rlq.inters)
}
// CountX is like Count, but panics if an error occurs.
func (rlq *ReportLicenseQuery) CountX(ctx context.Context) int {
count, err := rlq.Count(ctx)
if err != nil {
panic(err)
}
return count
}
// Exist returns true if the query has elements in the graph.
func (rlq *ReportLicenseQuery) Exist(ctx context.Context) (bool, error) {
ctx = setContextOp(ctx, rlq.ctx, ent.OpQueryExist)
switch _, err := rlq.FirstID(ctx); {
case IsNotFound(err):
return false, nil
case err != nil:
return false, fmt.Errorf("ent: check existence: %w", err)
default:
return true, nil
}
}
// ExistX is like Exist, but panics if an error occurs.
func (rlq *ReportLicenseQuery) ExistX(ctx context.Context) bool {
exist, err := rlq.Exist(ctx)
if err != nil {
panic(err)
}
return exist
}
// Clone returns a duplicate of the ReportLicenseQuery builder, including all associated steps. It can be
// used to prepare common query builders and use them differently after the clone is made.
func (rlq *ReportLicenseQuery) Clone() *ReportLicenseQuery {
if rlq == nil {
return nil
}
return &ReportLicenseQuery{
config: rlq.config,
ctx: rlq.ctx.Clone(),
order: append([]reportlicense.OrderOption{}, rlq.order...),
inters: append([]Interceptor{}, rlq.inters...),
predicates: append([]predicate.ReportLicense{}, rlq.predicates...),
withPackage: rlq.withPackage.Clone(),
// clone intermediate query.
sql: rlq.sql.Clone(),
path: rlq.path,
}
}
// WithPackage tells the query-builder to eager-load the nodes that are connected to
// the "package" edge. The optional arguments are used to configure the query builder of the edge.
func (rlq *ReportLicenseQuery) WithPackage(opts ...func(*ReportPackageQuery)) *ReportLicenseQuery {
query := (&ReportPackageClient{config: rlq.config}).Query()
for _, opt := range opts {
opt(query)
}
rlq.withPackage = query
return rlq
}
// GroupBy is used to group vertices by one or more fields/columns.
// It is often used with aggregate functions, like: count, max, mean, min, sum.
//
// Example:
//
// var v []struct {
// LicenseID string `json:"license_id,omitempty"`
// Count int `json:"count,omitempty"`
// }
//
// client.ReportLicense.Query().
// GroupBy(reportlicense.FieldLicenseID).
// Aggregate(ent.Count()).
// Scan(ctx, &v)
func (rlq *ReportLicenseQuery) GroupBy(field string, fields ...string) *ReportLicenseGroupBy {
rlq.ctx.Fields = append([]string{field}, fields...)
grbuild := &ReportLicenseGroupBy{build: rlq}
grbuild.flds = &rlq.ctx.Fields
grbuild.label = reportlicense.Label
grbuild.scan = grbuild.Scan
return grbuild
}
// Select allows the selection one or more fields/columns for the given query,
// instead of selecting all fields in the entity.
//
// Example:
//
// var v []struct {
// LicenseID string `json:"license_id,omitempty"`
// }
//
// client.ReportLicense.Query().
// Select(reportlicense.FieldLicenseID).
// Scan(ctx, &v)
func (rlq *ReportLicenseQuery) Select(fields ...string) *ReportLicenseSelect {
rlq.ctx.Fields = append(rlq.ctx.Fields, fields...)
sbuild := &ReportLicenseSelect{ReportLicenseQuery: rlq}
sbuild.label = reportlicense.Label
sbuild.flds, sbuild.scan = &rlq.ctx.Fields, sbuild.Scan
return sbuild
}
// Aggregate returns a ReportLicenseSelect configured with the given aggregations.
func (rlq *ReportLicenseQuery) Aggregate(fns ...AggregateFunc) *ReportLicenseSelect {
return rlq.Select().Aggregate(fns...)
}
func (rlq *ReportLicenseQuery) prepareQuery(ctx context.Context) error {
for _, inter := range rlq.inters {
if inter == nil {
return fmt.Errorf("ent: uninitialized interceptor (forgotten import ent/runtime?)")
}
if trv, ok := inter.(Traverser); ok {
if err := trv.Traverse(ctx, rlq); err != nil {
return err
}
}
}
for _, f := range rlq.ctx.Fields {
if !reportlicense.ValidColumn(f) {
return &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
}
if rlq.path != nil {
prev, err := rlq.path(ctx)
if err != nil {
return err
}
rlq.sql = prev
}
return nil
}
func (rlq *ReportLicenseQuery) sqlAll(ctx context.Context, hooks ...queryHook) ([]*ReportLicense, error) {
var (
nodes = []*ReportLicense{}
withFKs = rlq.withFKs
_spec = rlq.querySpec()
loadedTypes = [1]bool{
rlq.withPackage != nil,
}
)
if rlq.withPackage != nil {
withFKs = true
}
if withFKs {
_spec.Node.Columns = append(_spec.Node.Columns, reportlicense.ForeignKeys...)
}
_spec.ScanValues = func(columns []string) ([]any, error) {
return (*ReportLicense).scanValues(nil, columns)
}
_spec.Assign = func(columns []string, values []any) error {
node := &ReportLicense{config: rlq.config}
nodes = append(nodes, node)
node.Edges.loadedTypes = loadedTypes
return node.assignValues(columns, values)
}
for i := range hooks {
hooks[i](ctx, _spec)
}
if err := sqlgraph.QueryNodes(ctx, rlq.driver, _spec); err != nil {
return nil, err
}
if len(nodes) == 0 {
return nodes, nil
}
if query := rlq.withPackage; query != nil {
if err := rlq.loadPackage(ctx, query, nodes, nil,
func(n *ReportLicense, e *ReportPackage) { n.Edges.Package = e }); err != nil {
return nil, err
}
}
return nodes, nil
}
func (rlq *ReportLicenseQuery) loadPackage(ctx context.Context, query *ReportPackageQuery, nodes []*ReportLicense, init func(*ReportLicense), assign func(*ReportLicense, *ReportPackage)) error {
ids := make([]int, 0, len(nodes))
nodeids := make(map[int][]*ReportLicense)
for i := range nodes {
if nodes[i].report_package_licenses == nil {
continue
}
fk := *nodes[i].report_package_licenses
if _, ok := nodeids[fk]; !ok {
ids = append(ids, fk)
}
nodeids[fk] = append(nodeids[fk], nodes[i])
}
if len(ids) == 0 {
return nil
}
query.Where(reportpackage.IDIn(ids...))
neighbors, err := query.All(ctx)
if err != nil {
return err
}
for _, n := range neighbors {
nodes, ok := nodeids[n.ID]
if !ok {
return fmt.Errorf(`unexpected foreign-key "report_package_licenses" returned %v`, n.ID)
}
for i := range nodes {
assign(nodes[i], n)
}
}
return nil
}
func (rlq *ReportLicenseQuery) sqlCount(ctx context.Context) (int, error) {
_spec := rlq.querySpec()
_spec.Node.Columns = rlq.ctx.Fields
if len(rlq.ctx.Fields) > 0 {
_spec.Unique = rlq.ctx.Unique != nil && *rlq.ctx.Unique
}
return sqlgraph.CountNodes(ctx, rlq.driver, _spec)
}
func (rlq *ReportLicenseQuery) querySpec() *sqlgraph.QuerySpec {
_spec := sqlgraph.NewQuerySpec(reportlicense.Table, reportlicense.Columns, sqlgraph.NewFieldSpec(reportlicense.FieldID, field.TypeInt))
_spec.From = rlq.sql
if unique := rlq.ctx.Unique; unique != nil {
_spec.Unique = *unique
} else if rlq.path != nil {
_spec.Unique = true
}
if fields := rlq.ctx.Fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportlicense.FieldID)
for i := range fields {
if fields[i] != reportlicense.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, fields[i])
}
}
}
if ps := rlq.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if limit := rlq.ctx.Limit; limit != nil {
_spec.Limit = *limit
}
if offset := rlq.ctx.Offset; offset != nil {
_spec.Offset = *offset
}
if ps := rlq.order; len(ps) > 0 {
_spec.Order = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
return _spec
}
func (rlq *ReportLicenseQuery) sqlQuery(ctx context.Context) *sql.Selector {
builder := sql.Dialect(rlq.driver.Dialect())
t1 := builder.Table(reportlicense.Table)
columns := rlq.ctx.Fields
if len(columns) == 0 {
columns = reportlicense.Columns
}
selector := builder.Select(t1.Columns(columns...)...).From(t1)
if rlq.sql != nil {
selector = rlq.sql
selector.Select(selector.Columns(columns...)...)
}
if rlq.ctx.Unique != nil && *rlq.ctx.Unique {
selector.Distinct()
}
for _, p := range rlq.predicates {
p(selector)
}
for _, p := range rlq.order {
p(selector)
}
if offset := rlq.ctx.Offset; offset != nil {
// limit is mandatory for offset clause. We start
// with default value, and override it below if needed.
selector.Offset(*offset).Limit(math.MaxInt32)
}
if limit := rlq.ctx.Limit; limit != nil {
selector.Limit(*limit)
}
return selector
}
// ReportLicenseGroupBy is the group-by builder for ReportLicense entities.
type ReportLicenseGroupBy struct {
selector
build *ReportLicenseQuery
}
// Aggregate adds the given aggregation functions to the group-by query.
func (rlgb *ReportLicenseGroupBy) Aggregate(fns ...AggregateFunc) *ReportLicenseGroupBy {
rlgb.fns = append(rlgb.fns, fns...)
return rlgb
}
// Scan applies the selector query and scans the result into the given value.
func (rlgb *ReportLicenseGroupBy) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rlgb.build.ctx, ent.OpQueryGroupBy)
if err := rlgb.build.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportLicenseQuery, *ReportLicenseGroupBy](ctx, rlgb.build, rlgb, rlgb.build.inters, v)
}
func (rlgb *ReportLicenseGroupBy) sqlScan(ctx context.Context, root *ReportLicenseQuery, v any) error {
selector := root.sqlQuery(ctx).Select()
aggregation := make([]string, 0, len(rlgb.fns))
for _, fn := range rlgb.fns {
aggregation = append(aggregation, fn(selector))
}
if len(selector.SelectedColumns()) == 0 {
columns := make([]string, 0, len(*rlgb.flds)+len(rlgb.fns))
for _, f := range *rlgb.flds {
columns = append(columns, selector.C(f))
}
columns = append(columns, aggregation...)
selector.Select(columns...)
}
selector.GroupBy(selector.Columns(*rlgb.flds...)...)
if err := selector.Err(); err != nil {
return err
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rlgb.build.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}
// ReportLicenseSelect is the builder for selecting fields of ReportLicense entities.
type ReportLicenseSelect struct {
*ReportLicenseQuery
selector
}
// Aggregate adds the given aggregation functions to the selector query.
func (rls *ReportLicenseSelect) Aggregate(fns ...AggregateFunc) *ReportLicenseSelect {
rls.fns = append(rls.fns, fns...)
return rls
}
// Scan applies the selector query and scans the result into the given value.
func (rls *ReportLicenseSelect) Scan(ctx context.Context, v any) error {
ctx = setContextOp(ctx, rls.ctx, ent.OpQuerySelect)
if err := rls.prepareQuery(ctx); err != nil {
return err
}
return scanWithInterceptors[*ReportLicenseQuery, *ReportLicenseSelect](ctx, rls.ReportLicenseQuery, rls, rls.inters, v)
}
func (rls *ReportLicenseSelect) sqlScan(ctx context.Context, root *ReportLicenseQuery, v any) error {
selector := root.sqlQuery(ctx)
aggregation := make([]string, 0, len(rls.fns))
for _, fn := range rls.fns {
aggregation = append(aggregation, fn(selector))
}
switch n := len(*rls.selector.flds); {
case n == 0 && len(aggregation) > 0:
selector.Select(aggregation...)
case n != 0 && len(aggregation) > 0:
selector.AppendSelect(aggregation...)
}
rows := &sql.Rows{}
query, args := selector.Query()
if err := rls.driver.Query(ctx, query, args, rows); err != nil {
return err
}
defer rows.Close()
return sql.ScanSlice(rows, v)
}

605
ent/reportlicense_update.go Normal file
View File

@ -0,0 +1,605 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"context"
"errors"
"fmt"
"time"
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
"entgo.io/ent/schema/field"
"github.com/safedep/vet/ent/predicate"
"github.com/safedep/vet/ent/reportlicense"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportLicenseUpdate is the builder for updating ReportLicense entities.
type ReportLicenseUpdate struct {
config
hooks []Hook
mutation *ReportLicenseMutation
}
// Where appends a list predicates to the ReportLicenseUpdate builder.
func (rlu *ReportLicenseUpdate) Where(ps ...predicate.ReportLicense) *ReportLicenseUpdate {
rlu.mutation.Where(ps...)
return rlu
}
// SetLicenseID sets the "license_id" field.
func (rlu *ReportLicenseUpdate) SetLicenseID(s string) *ReportLicenseUpdate {
rlu.mutation.SetLicenseID(s)
return rlu
}
// SetNillableLicenseID sets the "license_id" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableLicenseID(s *string) *ReportLicenseUpdate {
if s != nil {
rlu.SetLicenseID(*s)
}
return rlu
}
// SetName sets the "name" field.
func (rlu *ReportLicenseUpdate) SetName(s string) *ReportLicenseUpdate {
rlu.mutation.SetName(s)
return rlu
}
// SetNillableName sets the "name" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableName(s *string) *ReportLicenseUpdate {
if s != nil {
rlu.SetName(*s)
}
return rlu
}
// ClearName clears the value of the "name" field.
func (rlu *ReportLicenseUpdate) ClearName() *ReportLicenseUpdate {
rlu.mutation.ClearName()
return rlu
}
// SetSpdxID sets the "spdx_id" field.
func (rlu *ReportLicenseUpdate) SetSpdxID(s string) *ReportLicenseUpdate {
rlu.mutation.SetSpdxID(s)
return rlu
}
// SetNillableSpdxID sets the "spdx_id" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableSpdxID(s *string) *ReportLicenseUpdate {
if s != nil {
rlu.SetSpdxID(*s)
}
return rlu
}
// ClearSpdxID clears the value of the "spdx_id" field.
func (rlu *ReportLicenseUpdate) ClearSpdxID() *ReportLicenseUpdate {
rlu.mutation.ClearSpdxID()
return rlu
}
// SetURL sets the "url" field.
func (rlu *ReportLicenseUpdate) SetURL(s string) *ReportLicenseUpdate {
rlu.mutation.SetURL(s)
return rlu
}
// SetNillableURL sets the "url" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableURL(s *string) *ReportLicenseUpdate {
if s != nil {
rlu.SetURL(*s)
}
return rlu
}
// ClearURL clears the value of the "url" field.
func (rlu *ReportLicenseUpdate) ClearURL() *ReportLicenseUpdate {
rlu.mutation.ClearURL()
return rlu
}
// SetCreatedAt sets the "created_at" field.
func (rlu *ReportLicenseUpdate) SetCreatedAt(t time.Time) *ReportLicenseUpdate {
rlu.mutation.SetCreatedAt(t)
return rlu
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableCreatedAt(t *time.Time) *ReportLicenseUpdate {
if t != nil {
rlu.SetCreatedAt(*t)
}
return rlu
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rlu *ReportLicenseUpdate) ClearCreatedAt() *ReportLicenseUpdate {
rlu.mutation.ClearCreatedAt()
return rlu
}
// SetUpdatedAt sets the "updated_at" field.
func (rlu *ReportLicenseUpdate) SetUpdatedAt(t time.Time) *ReportLicenseUpdate {
rlu.mutation.SetUpdatedAt(t)
return rlu
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillableUpdatedAt(t *time.Time) *ReportLicenseUpdate {
if t != nil {
rlu.SetUpdatedAt(*t)
}
return rlu
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rlu *ReportLicenseUpdate) ClearUpdatedAt() *ReportLicenseUpdate {
rlu.mutation.ClearUpdatedAt()
return rlu
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rlu *ReportLicenseUpdate) SetPackageID(id int) *ReportLicenseUpdate {
rlu.mutation.SetPackageID(id)
return rlu
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rlu *ReportLicenseUpdate) SetNillablePackageID(id *int) *ReportLicenseUpdate {
if id != nil {
rlu = rlu.SetPackageID(*id)
}
return rlu
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rlu *ReportLicenseUpdate) SetPackage(r *ReportPackage) *ReportLicenseUpdate {
return rlu.SetPackageID(r.ID)
}
// Mutation returns the ReportLicenseMutation object of the builder.
func (rlu *ReportLicenseUpdate) Mutation() *ReportLicenseMutation {
return rlu.mutation
}
// ClearPackage clears the "package" edge to the ReportPackage entity.
func (rlu *ReportLicenseUpdate) ClearPackage() *ReportLicenseUpdate {
rlu.mutation.ClearPackage()
return rlu
}
// Save executes the query and returns the number of nodes affected by the update operation.
func (rlu *ReportLicenseUpdate) Save(ctx context.Context) (int, error) {
return withHooks(ctx, rlu.sqlSave, rlu.mutation, rlu.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rlu *ReportLicenseUpdate) SaveX(ctx context.Context) int {
affected, err := rlu.Save(ctx)
if err != nil {
panic(err)
}
return affected
}
// Exec executes the query.
func (rlu *ReportLicenseUpdate) Exec(ctx context.Context) error {
_, err := rlu.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rlu *ReportLicenseUpdate) ExecX(ctx context.Context) {
if err := rlu.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rlu *ReportLicenseUpdate) check() error {
if v, ok := rlu.mutation.LicenseID(); ok {
if err := reportlicense.LicenseIDValidator(v); err != nil {
return &ValidationError{Name: "license_id", err: fmt.Errorf(`ent: validator failed for field "ReportLicense.license_id": %w`, err)}
}
}
return nil
}
func (rlu *ReportLicenseUpdate) sqlSave(ctx context.Context) (n int, err error) {
if err := rlu.check(); err != nil {
return n, err
}
_spec := sqlgraph.NewUpdateSpec(reportlicense.Table, reportlicense.Columns, sqlgraph.NewFieldSpec(reportlicense.FieldID, field.TypeInt))
if ps := rlu.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rlu.mutation.LicenseID(); ok {
_spec.SetField(reportlicense.FieldLicenseID, field.TypeString, value)
}
if value, ok := rlu.mutation.Name(); ok {
_spec.SetField(reportlicense.FieldName, field.TypeString, value)
}
if rlu.mutation.NameCleared() {
_spec.ClearField(reportlicense.FieldName, field.TypeString)
}
if value, ok := rlu.mutation.SpdxID(); ok {
_spec.SetField(reportlicense.FieldSpdxID, field.TypeString, value)
}
if rlu.mutation.SpdxIDCleared() {
_spec.ClearField(reportlicense.FieldSpdxID, field.TypeString)
}
if value, ok := rlu.mutation.URL(); ok {
_spec.SetField(reportlicense.FieldURL, field.TypeString, value)
}
if rlu.mutation.URLCleared() {
_spec.ClearField(reportlicense.FieldURL, field.TypeString)
}
if value, ok := rlu.mutation.CreatedAt(); ok {
_spec.SetField(reportlicense.FieldCreatedAt, field.TypeTime, value)
}
if rlu.mutation.CreatedAtCleared() {
_spec.ClearField(reportlicense.FieldCreatedAt, field.TypeTime)
}
if value, ok := rlu.mutation.UpdatedAt(); ok {
_spec.SetField(reportlicense.FieldUpdatedAt, field.TypeTime, value)
}
if rlu.mutation.UpdatedAtCleared() {
_spec.ClearField(reportlicense.FieldUpdatedAt, field.TypeTime)
}
if rlu.mutation.PackageCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportlicense.PackageTable,
Columns: []string{reportlicense.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := rlu.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportlicense.PackageTable,
Columns: []string{reportlicense.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
if n, err = sqlgraph.UpdateNodes(ctx, rlu.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportlicense.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return 0, err
}
rlu.mutation.done = true
return n, nil
}
// ReportLicenseUpdateOne is the builder for updating a single ReportLicense entity.
type ReportLicenseUpdateOne struct {
config
fields []string
hooks []Hook
mutation *ReportLicenseMutation
}
// SetLicenseID sets the "license_id" field.
func (rluo *ReportLicenseUpdateOne) SetLicenseID(s string) *ReportLicenseUpdateOne {
rluo.mutation.SetLicenseID(s)
return rluo
}
// SetNillableLicenseID sets the "license_id" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableLicenseID(s *string) *ReportLicenseUpdateOne {
if s != nil {
rluo.SetLicenseID(*s)
}
return rluo
}
// SetName sets the "name" field.
func (rluo *ReportLicenseUpdateOne) SetName(s string) *ReportLicenseUpdateOne {
rluo.mutation.SetName(s)
return rluo
}
// SetNillableName sets the "name" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableName(s *string) *ReportLicenseUpdateOne {
if s != nil {
rluo.SetName(*s)
}
return rluo
}
// ClearName clears the value of the "name" field.
func (rluo *ReportLicenseUpdateOne) ClearName() *ReportLicenseUpdateOne {
rluo.mutation.ClearName()
return rluo
}
// SetSpdxID sets the "spdx_id" field.
func (rluo *ReportLicenseUpdateOne) SetSpdxID(s string) *ReportLicenseUpdateOne {
rluo.mutation.SetSpdxID(s)
return rluo
}
// SetNillableSpdxID sets the "spdx_id" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableSpdxID(s *string) *ReportLicenseUpdateOne {
if s != nil {
rluo.SetSpdxID(*s)
}
return rluo
}
// ClearSpdxID clears the value of the "spdx_id" field.
func (rluo *ReportLicenseUpdateOne) ClearSpdxID() *ReportLicenseUpdateOne {
rluo.mutation.ClearSpdxID()
return rluo
}
// SetURL sets the "url" field.
func (rluo *ReportLicenseUpdateOne) SetURL(s string) *ReportLicenseUpdateOne {
rluo.mutation.SetURL(s)
return rluo
}
// SetNillableURL sets the "url" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableURL(s *string) *ReportLicenseUpdateOne {
if s != nil {
rluo.SetURL(*s)
}
return rluo
}
// ClearURL clears the value of the "url" field.
func (rluo *ReportLicenseUpdateOne) ClearURL() *ReportLicenseUpdateOne {
rluo.mutation.ClearURL()
return rluo
}
// SetCreatedAt sets the "created_at" field.
func (rluo *ReportLicenseUpdateOne) SetCreatedAt(t time.Time) *ReportLicenseUpdateOne {
rluo.mutation.SetCreatedAt(t)
return rluo
}
// SetNillableCreatedAt sets the "created_at" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableCreatedAt(t *time.Time) *ReportLicenseUpdateOne {
if t != nil {
rluo.SetCreatedAt(*t)
}
return rluo
}
// ClearCreatedAt clears the value of the "created_at" field.
func (rluo *ReportLicenseUpdateOne) ClearCreatedAt() *ReportLicenseUpdateOne {
rluo.mutation.ClearCreatedAt()
return rluo
}
// SetUpdatedAt sets the "updated_at" field.
func (rluo *ReportLicenseUpdateOne) SetUpdatedAt(t time.Time) *ReportLicenseUpdateOne {
rluo.mutation.SetUpdatedAt(t)
return rluo
}
// SetNillableUpdatedAt sets the "updated_at" field if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillableUpdatedAt(t *time.Time) *ReportLicenseUpdateOne {
if t != nil {
rluo.SetUpdatedAt(*t)
}
return rluo
}
// ClearUpdatedAt clears the value of the "updated_at" field.
func (rluo *ReportLicenseUpdateOne) ClearUpdatedAt() *ReportLicenseUpdateOne {
rluo.mutation.ClearUpdatedAt()
return rluo
}
// SetPackageID sets the "package" edge to the ReportPackage entity by ID.
func (rluo *ReportLicenseUpdateOne) SetPackageID(id int) *ReportLicenseUpdateOne {
rluo.mutation.SetPackageID(id)
return rluo
}
// SetNillablePackageID sets the "package" edge to the ReportPackage entity by ID if the given value is not nil.
func (rluo *ReportLicenseUpdateOne) SetNillablePackageID(id *int) *ReportLicenseUpdateOne {
if id != nil {
rluo = rluo.SetPackageID(*id)
}
return rluo
}
// SetPackage sets the "package" edge to the ReportPackage entity.
func (rluo *ReportLicenseUpdateOne) SetPackage(r *ReportPackage) *ReportLicenseUpdateOne {
return rluo.SetPackageID(r.ID)
}
// Mutation returns the ReportLicenseMutation object of the builder.
func (rluo *ReportLicenseUpdateOne) Mutation() *ReportLicenseMutation {
return rluo.mutation
}
// ClearPackage clears the "package" edge to the ReportPackage entity.
func (rluo *ReportLicenseUpdateOne) ClearPackage() *ReportLicenseUpdateOne {
rluo.mutation.ClearPackage()
return rluo
}
// Where appends a list predicates to the ReportLicenseUpdate builder.
func (rluo *ReportLicenseUpdateOne) Where(ps ...predicate.ReportLicense) *ReportLicenseUpdateOne {
rluo.mutation.Where(ps...)
return rluo
}
// Select allows selecting one or more fields (columns) of the returned entity.
// The default is selecting all fields defined in the entity schema.
func (rluo *ReportLicenseUpdateOne) Select(field string, fields ...string) *ReportLicenseUpdateOne {
rluo.fields = append([]string{field}, fields...)
return rluo
}
// Save executes the query and returns the updated ReportLicense entity.
func (rluo *ReportLicenseUpdateOne) Save(ctx context.Context) (*ReportLicense, error) {
return withHooks(ctx, rluo.sqlSave, rluo.mutation, rluo.hooks)
}
// SaveX is like Save, but panics if an error occurs.
func (rluo *ReportLicenseUpdateOne) SaveX(ctx context.Context) *ReportLicense {
node, err := rluo.Save(ctx)
if err != nil {
panic(err)
}
return node
}
// Exec executes the query on the entity.
func (rluo *ReportLicenseUpdateOne) Exec(ctx context.Context) error {
_, err := rluo.Save(ctx)
return err
}
// ExecX is like Exec, but panics if an error occurs.
func (rluo *ReportLicenseUpdateOne) ExecX(ctx context.Context) {
if err := rluo.Exec(ctx); err != nil {
panic(err)
}
}
// check runs all checks and user-defined validators on the builder.
func (rluo *ReportLicenseUpdateOne) check() error {
if v, ok := rluo.mutation.LicenseID(); ok {
if err := reportlicense.LicenseIDValidator(v); err != nil {
return &ValidationError{Name: "license_id", err: fmt.Errorf(`ent: validator failed for field "ReportLicense.license_id": %w`, err)}
}
}
return nil
}
func (rluo *ReportLicenseUpdateOne) sqlSave(ctx context.Context) (_node *ReportLicense, err error) {
if err := rluo.check(); err != nil {
return _node, err
}
_spec := sqlgraph.NewUpdateSpec(reportlicense.Table, reportlicense.Columns, sqlgraph.NewFieldSpec(reportlicense.FieldID, field.TypeInt))
id, ok := rluo.mutation.ID()
if !ok {
return nil, &ValidationError{Name: "id", err: errors.New(`ent: missing "ReportLicense.id" for update`)}
}
_spec.Node.ID.Value = id
if fields := rluo.fields; len(fields) > 0 {
_spec.Node.Columns = make([]string, 0, len(fields))
_spec.Node.Columns = append(_spec.Node.Columns, reportlicense.FieldID)
for _, f := range fields {
if !reportlicense.ValidColumn(f) {
return nil, &ValidationError{Name: f, err: fmt.Errorf("ent: invalid field %q for query", f)}
}
if f != reportlicense.FieldID {
_spec.Node.Columns = append(_spec.Node.Columns, f)
}
}
}
if ps := rluo.mutation.predicates; len(ps) > 0 {
_spec.Predicate = func(selector *sql.Selector) {
for i := range ps {
ps[i](selector)
}
}
}
if value, ok := rluo.mutation.LicenseID(); ok {
_spec.SetField(reportlicense.FieldLicenseID, field.TypeString, value)
}
if value, ok := rluo.mutation.Name(); ok {
_spec.SetField(reportlicense.FieldName, field.TypeString, value)
}
if rluo.mutation.NameCleared() {
_spec.ClearField(reportlicense.FieldName, field.TypeString)
}
if value, ok := rluo.mutation.SpdxID(); ok {
_spec.SetField(reportlicense.FieldSpdxID, field.TypeString, value)
}
if rluo.mutation.SpdxIDCleared() {
_spec.ClearField(reportlicense.FieldSpdxID, field.TypeString)
}
if value, ok := rluo.mutation.URL(); ok {
_spec.SetField(reportlicense.FieldURL, field.TypeString, value)
}
if rluo.mutation.URLCleared() {
_spec.ClearField(reportlicense.FieldURL, field.TypeString)
}
if value, ok := rluo.mutation.CreatedAt(); ok {
_spec.SetField(reportlicense.FieldCreatedAt, field.TypeTime, value)
}
if rluo.mutation.CreatedAtCleared() {
_spec.ClearField(reportlicense.FieldCreatedAt, field.TypeTime)
}
if value, ok := rluo.mutation.UpdatedAt(); ok {
_spec.SetField(reportlicense.FieldUpdatedAt, field.TypeTime, value)
}
if rluo.mutation.UpdatedAtCleared() {
_spec.ClearField(reportlicense.FieldUpdatedAt, field.TypeTime)
}
if rluo.mutation.PackageCleared() {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportlicense.PackageTable,
Columns: []string{reportlicense.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
_spec.Edges.Clear = append(_spec.Edges.Clear, edge)
}
if nodes := rluo.mutation.PackageIDs(); len(nodes) > 0 {
edge := &sqlgraph.EdgeSpec{
Rel: sqlgraph.M2O,
Inverse: true,
Table: reportlicense.PackageTable,
Columns: []string{reportlicense.PackageColumn},
Bidi: false,
Target: &sqlgraph.EdgeTarget{
IDSpec: sqlgraph.NewFieldSpec(reportpackage.FieldID, field.TypeInt),
},
}
for _, k := range nodes {
edge.Target.Nodes = append(edge.Target.Nodes, k)
}
_spec.Edges.Add = append(_spec.Edges.Add, edge)
}
_node = &ReportLicense{config: rluo.config}
_spec.Assign = _node.assignValues
_spec.ScanValues = _node.scanValues
if err = sqlgraph.UpdateNode(ctx, rluo.driver, _spec); err != nil {
if _, ok := err.(*sqlgraph.NotFoundError); ok {
err = &NotFoundError{reportlicense.Label}
} else if sqlgraph.IsConstraintError(err) {
err = &ConstraintError{msg: err.Error(), wrap: err}
}
return nil, err
}
rluo.mutation.done = true
return _node, nil
}

231
ent/reportmalware.go Normal file
View File

@ -0,0 +1,231 @@
// Code generated by ent, DO NOT EDIT.
package ent
import (
"encoding/json"
"fmt"
"strings"
"time"
"entgo.io/ent"
"entgo.io/ent/dialect/sql"
"github.com/safedep/vet/ent/reportmalware"
"github.com/safedep/vet/ent/reportpackage"
)
// ReportMalware is the model entity for the ReportMalware schema.
type ReportMalware struct {
config `json:"-"`
// ID of the ent.
ID int `json:"id,omitempty"`
// AnalysisID holds the value of the "analysis_id" field.
AnalysisID string `json:"analysis_id,omitempty"`
// IsMalware holds the value of the "is_malware" field.
IsMalware bool `json:"is_malware,omitempty"`
// IsSuspicious holds the value of the "is_suspicious" field.
IsSuspicious bool `json:"is_suspicious,omitempty"`
// Confidence holds the value of the "confidence" field.
Confidence string `json:"confidence,omitempty"`
// Report holds the value of the "report" field.
Report map[string]interface{} `json:"report,omitempty"`
// VerificationRecord holds the value of the "verification_record" field.
VerificationRecord map[string]interface{} `json:"verification_record,omitempty"`
// CreatedAt holds the value of the "created_at" field.
CreatedAt time.Time `json:"created_at,omitempty"`
// UpdatedAt holds the value of the "updated_at" field.
UpdatedAt time.Time `json:"updated_at,omitempty"`
// Edges holds the relations/edges for other nodes in the graph.
// The values are being populated by the ReportMalwareQuery when eager-loading is set.
Edges ReportMalwareEdges `json:"edges"`
report_package_malware_analysis *int
selectValues sql.SelectValues
}
// ReportMalwareEdges holds the relations/edges for other nodes in the graph.
type ReportMalwareEdges struct {
// Package holds the value of the package edge.
Package *ReportPackage `json:"package,omitempty"`
// loadedTypes holds the information for reporting if a
// type was loaded (or requested) in eager-loading or not.
loadedTypes [1]bool
}
// PackageOrErr returns the Package value or an error if the edge
// was not loaded in eager-loading, or loaded but was not found.
func (e ReportMalwareEdges) PackageOrErr() (*ReportPackage, error) {
if e.Package != nil {
return e.Package, nil
} else if e.loadedTypes[0] {
return nil, &NotFoundError{label: reportpackage.Label}
}
return nil, &NotLoadedError{edge: "package"}
}
// scanValues returns the types for scanning values from sql.Rows.
func (*ReportMalware) scanValues(columns []string) ([]any, error) {
values := make([]any, len(columns))
for i := range columns {
switch columns[i] {
case reportmalware.FieldReport, reportmalware.FieldVerificationRecord:
values[i] = new([]byte)
case reportmalware.FieldIsMalware, reportmalware.FieldIsSuspicious:
values[i] = new(sql.NullBool)
case reportmalware.FieldID:
values[i] = new(sql.NullInt64)
case reportmalware.FieldAnalysisID, reportmalware.FieldConfidence:
values[i] = new(sql.NullString)
case reportmalware.FieldCreatedAt, reportmalware.FieldUpdatedAt:
values[i] = new(sql.NullTime)
case reportmalware.ForeignKeys[0]: // report_package_malware_analysis
values[i] = new(sql.NullInt64)
default:
values[i] = new(sql.UnknownType)
}
}
return values, nil
}
// assignValues assigns the values that were returned from sql.Rows (after scanning)
// to the ReportMalware fields.
func (rm *ReportMalware) assignValues(columns []string, values []any) error {
if m, n := len(values), len(columns); m < n {
return fmt.Errorf("mismatch number of scan values: %d != %d", m, n)
}
for i := range columns {
switch columns[i] {
case reportmalware.FieldID:
value, ok := values[i].(*sql.NullInt64)
if !ok {
return fmt.Errorf("unexpected type %T for field id", value)
}
rm.ID = int(value.Int64)
case reportmalware.FieldAnalysisID:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field analysis_id", values[i])
} else if value.Valid {
rm.AnalysisID = value.String
}
case reportmalware.FieldIsMalware:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field is_malware", values[i])
} else if value.Valid {
rm.IsMalware = value.Bool
}
case reportmalware.FieldIsSuspicious:
if value, ok := values[i].(*sql.NullBool); !ok {
return fmt.Errorf("unexpected type %T for field is_suspicious", values[i])
} else if value.Valid {
rm.IsSuspicious = value.Bool
}
case reportmalware.FieldConfidence:
if value, ok := values[i].(*sql.NullString); !ok {
return fmt.Errorf("unexpected type %T for field confidence", values[i])
} else if value.Valid {
rm.Confidence = value.String
}
case reportmalware.FieldReport:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field report", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &rm.Report); err != nil {
return fmt.Errorf("unmarshal field report: %w", err)
}
}
case reportmalware.FieldVerificationRecord:
if value, ok := values[i].(*[]byte); !ok {
return fmt.Errorf("unexpected type %T for field verification_record", values[i])
} else if value != nil && len(*value) > 0 {
if err := json.Unmarshal(*value, &rm.VerificationRecord); err != nil {
return fmt.Errorf("unmarshal field verification_record: %w", err)
}
}
case reportmalware.FieldCreatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field created_at", values[i])
} else if value.Valid {
rm.CreatedAt = value.Time
}
case reportmalware.FieldUpdatedAt:
if value, ok := values[i].(*sql.NullTime); !ok {
return fmt.Errorf("unexpected type %T for field updated_at", values[i])
} else if value.Valid {
rm.UpdatedAt = value.Time
}
case reportmalware.ForeignKeys[0]:
if value, ok := values[i].(*sql.NullInt64); !ok {
return fmt.Errorf("unexpected type %T for edge-field report_package_malware_analysis", value)
} else if value.Valid {
rm.report_package_malware_analysis = new(int)
*rm.report_package_malware_analysis = int(value.Int64)
}
default:
rm.selectValues.Set(columns[i], values[i])
}
}
return nil
}
// Value returns the ent.Value that was dynamically selected and assigned to the ReportMalware.
// This includes values selected through modifiers, order, etc.
func (rm *ReportMalware) Value(name string) (ent.Value, error) {
return rm.selectValues.Get(name)
}
// QueryPackage queries the "package" edge of the ReportMalware entity.
func (rm *ReportMalware) QueryPackage() *ReportPackageQuery {
return NewReportMalwareClient(rm.config).QueryPackage(rm)
}
// Update returns a builder for updating this ReportMalware.
// Note that you need to call ReportMalware.Unwrap() before calling this method if this ReportMalware
// was returned from a transaction, and the transaction was committed or rolled back.
func (rm *ReportMalware) Update() *ReportMalwareUpdateOne {
return NewReportMalwareClient(rm.config).UpdateOne(rm)
}
// Unwrap unwraps the ReportMalware entity that was returned from a transaction after it was closed,
// so that all future queries will be executed through the driver which created the transaction.
func (rm *ReportMalware) Unwrap() *ReportMalware {
_tx, ok := rm.config.driver.(*txDriver)
if !ok {
panic("ent: ReportMalware is not a transactional entity")
}
rm.config.driver = _tx.drv
return rm
}
// String implements the fmt.Stringer.
func (rm *ReportMalware) String() string {
var builder strings.Builder
builder.WriteString("ReportMalware(")
builder.WriteString(fmt.Sprintf("id=%v, ", rm.ID))
builder.WriteString("analysis_id=")
builder.WriteString(rm.AnalysisID)
builder.WriteString(", ")
builder.WriteString("is_malware=")
builder.WriteString(fmt.Sprintf("%v", rm.IsMalware))
builder.WriteString(", ")
builder.WriteString("is_suspicious=")
builder.WriteString(fmt.Sprintf("%v", rm.IsSuspicious))
builder.WriteString(", ")
builder.WriteString("confidence=")
builder.WriteString(rm.Confidence)
builder.WriteString(", ")
builder.WriteString("report=")
builder.WriteString(fmt.Sprintf("%v", rm.Report))
builder.WriteString(", ")
builder.WriteString("verification_record=")
builder.WriteString(fmt.Sprintf("%v", rm.VerificationRecord))
builder.WriteString(", ")
builder.WriteString("created_at=")
builder.WriteString(rm.CreatedAt.Format(time.ANSIC))
builder.WriteString(", ")
builder.WriteString("updated_at=")
builder.WriteString(rm.UpdatedAt.Format(time.ANSIC))
builder.WriteByte(')')
return builder.String()
}
// ReportMalwares is a parsable slice of ReportMalware.
type ReportMalwares []*ReportMalware

View File

@ -0,0 +1,137 @@
// Code generated by ent, DO NOT EDIT.
package reportmalware
import (
"entgo.io/ent/dialect/sql"
"entgo.io/ent/dialect/sql/sqlgraph"
)
const (
// Label holds the string label denoting the reportmalware type in the database.
Label = "report_malware"
// FieldID holds the string denoting the id field in the database.
FieldID = "id"
// FieldAnalysisID holds the string denoting the analysis_id field in the database.
FieldAnalysisID = "analysis_id"
// FieldIsMalware holds the string denoting the is_malware field in the database.
FieldIsMalware = "is_malware"
// FieldIsSuspicious holds the string denoting the is_suspicious field in the database.
FieldIsSuspicious = "is_suspicious"
// FieldConfidence holds the string denoting the confidence field in the database.
FieldConfidence = "confidence"
// FieldReport holds the string denoting the report field in the database.
FieldReport = "report"
// FieldVerificationRecord holds the string denoting the verification_record field in the database.
FieldVerificationRecord = "verification_record"
// FieldCreatedAt holds the string denoting the created_at field in the database.
FieldCreatedAt = "created_at"
// FieldUpdatedAt holds the string denoting the updated_at field in the database.
FieldUpdatedAt = "updated_at"
// EdgePackage holds the string denoting the package edge name in mutations.
EdgePackage = "package"
// Table holds the table name of the reportmalware in the database.
Table = "report_malwares"
// PackageTable is the table that holds the package relation/edge.
PackageTable = "report_malwares"
// PackageInverseTable is the table name for the ReportPackage entity.
// It exists in this package in order to avoid circular dependency with the "reportpackage" package.
PackageInverseTable = "report_packages"
// PackageColumn is the table column denoting the package relation/edge.
PackageColumn = "report_package_malware_analysis"
)
// Columns holds all SQL columns for reportmalware fields.
var Columns = []string{
FieldID,
FieldAnalysisID,
FieldIsMalware,
FieldIsSuspicious,
FieldConfidence,
FieldReport,
FieldVerificationRecord,
FieldCreatedAt,
FieldUpdatedAt,
}
// ForeignKeys holds the SQL foreign-keys that are owned by the "report_malwares"
// table and are not defined as standalone fields in the schema.
var ForeignKeys = []string{
"report_package_malware_analysis",
}
// ValidColumn reports if the column name is valid (part of the table columns).
func ValidColumn(column string) bool {
for i := range Columns {
if column == Columns[i] {
return true
}
}
for i := range ForeignKeys {
if column == ForeignKeys[i] {
return true
}
}
return false
}
var (
// AnalysisIDValidator is a validator for the "analysis_id" field. It is called by the builders before save.
AnalysisIDValidator func(string) error
// DefaultIsMalware holds the default value on creation for the "is_malware" field.
DefaultIsMalware bool
// DefaultIsSuspicious holds the default value on creation for the "is_suspicious" field.
DefaultIsSuspicious bool
)
// OrderOption defines the ordering options for the ReportMalware queries.
type OrderOption func(*sql.Selector)
// ByID orders the results by the id field.
func ByID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldID, opts...).ToFunc()
}
// ByAnalysisID orders the results by the analysis_id field.
func ByAnalysisID(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldAnalysisID, opts...).ToFunc()
}
// ByIsMalware orders the results by the is_malware field.
func ByIsMalware(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldIsMalware, opts...).ToFunc()
}
// ByIsSuspicious orders the results by the is_suspicious field.
func ByIsSuspicious(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldIsSuspicious, opts...).ToFunc()
}
// ByConfidence orders the results by the confidence field.
func ByConfidence(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldConfidence, opts...).ToFunc()
}
// ByCreatedAt orders the results by the created_at field.
func ByCreatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldCreatedAt, opts...).ToFunc()
}
// ByUpdatedAt orders the results by the updated_at field.
func ByUpdatedAt(opts ...sql.OrderTermOption) OrderOption {
return sql.OrderByField(FieldUpdatedAt, opts...).ToFunc()
}
// ByPackageField orders the results by package field.
func ByPackageField(field string, opts ...sql.OrderTermOption) OrderOption {
return func(s *sql.Selector) {
sqlgraph.OrderByNeighborTerms(s, newPackageStep(), sql.OrderByField(field, opts...))
}
}
func newPackageStep() *sqlgraph.Step {
return sqlgraph.NewStep(
sqlgraph.From(Table, FieldID),
sqlgraph.To(PackageInverseTable, FieldID),
sqlgraph.Edge(sqlgraph.O2O, true, PackageTable, PackageColumn),
)
}

Some files were not shown because too many files have changed in this diff Show More