{"id":14069219,"url":"https://github.com/kputnam/piggly","last_synced_at":"2025-09-13T13:34:51.131Z","repository":{"id":875134,"uuid":"617119","full_name":"kputnam/piggly","owner":"kputnam","description":"PL/pgSQL stored procedure code coverage tool","archived":false,"fork":false,"pushed_at":"2023-01-20T07:37:27.000Z","size":491,"stargazers_count":75,"open_issues_count":12,"forks_count":15,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-08-09T20:55:27.869Z","etag":null,"topics":["coverage","pgsql","stored-procedures"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kputnam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2010-04-19T02:29:33.000Z","updated_at":"2025-05-20T12:04:49.000Z","dependencies_parsed_at":"2023-02-12T00:31:20.444Z","dependency_job_id":null,"html_url":"https://github.com/kputnam/piggly","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/kputnam/piggly","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kputnam%2Fpiggly","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kputnam%2Fpiggly/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kputnam%2Fpiggly/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kputnam%2Fpiggly/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kputnam","download_url":"https://codeload.github.com/kputnam/piggly/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kputnam%2Fpiggly/sbom","scorecard":{"id":569102,"data":{"date":"2025-08-11","repo":{"name":"github.com/kputnam/piggly","commit":"5c46d972092ced50a880e4cb3281ff253e5c0fd6"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.3,"checks":[{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":0,"reason":"Found 1/20 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":5,"reason":"5 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-579w-22j4-4749","Warn: Project is vulnerable to: GHSA-76r7-hhxj-r776","Warn: Project is vulnerable to: GHSA-cr5q-6q9f-rq6q","Warn: Project is vulnerable to: GHSA-j6gc-792m-qgm2","Warn: Project is vulnerable to: GHSA-pj73-v5mw-pm9j"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 11 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-20T15:50:06.225Z","repository_id":875134,"created_at":"2025-08-20T15:50:06.225Z","updated_at":"2025-08-20T15:50:06.225Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274969667,"owners_count":25383117,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["coverage","pgsql","stored-procedures"],"created_at":"2024-08-13T07:06:43.484Z","updated_at":"2025-09-13T13:34:51.086Z","avatar_url":"https://github.com/kputnam.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"# Piggly\n\nCode coverage reports for PostgreSQL PL/pgSQL stored procedures\n\n![Screenshot](https://kputnam.github.io/piggly/images/example.png)\n\n## Purpose\n\nPL/pgSQL doesn't have much in the way of developer tools, and writing automated tests for\nstored procedures can be much easier when you know what you haven't tested. Code coverage\nallows you to see which parts of your code haven't been executed.\n\nPiggly is a tool (written in Ruby, but you can write your tests in any language) to track\ncode coverage of PostgreSQL PL/pgSQL stored procedures. It reports on code coverage to help\nyou identify untested parts of your code.\n\n## How Does It Work?\n\nPiggly tracks the execution of PostgreSQL's PL/pgSQL stored procedures by recompiling\nthe stored procedure with instrumentation code. Basically, RAISE WARNING statements notify the\nclient of an execution event (e.g., a branch condition evaluating to true or false). It records\nthese events and generates prettified source code that is annotated with coverage details.\n\n## Features\n\n* Readable and easily-navigable reports (see [example](http://kputnam.github.io/piggly/reports/index.html))\n* Language agnostic - write your tests in Ruby, Python, Java, SQL scripts etc\n* Branch, block, and loop coverage analysis\n* Instrumenting source-to-source compiler\n* Low test execution overhead\n* Reduced compilation times by use of disk caching\n* Possible to aggregate coverage across multiple runs\n\n## Limitations\n\n* Not all PL/pgSQL grammar is currently supported, but the grammar is easy to modify\n* Cannot parse nested dollar-quoted strings, eg $A$ ... $B$ ... $B$ ... $A$\n* SQL statements are not instrumented, so their branches (COALESCE, WHERE-clauses, etc) aren't tracked\n\n## Requirements\n\n* [Treetop](http://github.com/nathansobo/treetop): `gem install treetop`\n* The [ruby-pg driver](http://bitbucket.org/ged/ruby-pg/): `gem install pg`\n* The examples require ActiveRecord: `gem install activerecord`\n\n## How to Install\n\nTo install the latest from github:\n\n    $ git clone git://github.com/kputnam/piggly.git\n    $ cd piggly\n    $ bundle install\n    $ bundle exec rake spec\n\n    $ rake gem\n    $ gem install pkg/*.gem --no-rdoc --no-ri\n\nTo install the latest release:\n\n    $ gem install piggly\n\n## Usage\n\nYour stored procedures must already be loaded in the database. Configure your database connection in\na file named `config/database.yml` relative to where you want to run piggly. You can also specify the\n`-d PATH` to an existing configuration file. The contents of the file follow ActiveRecord conventions:\n\n    piggly:\n      adapter: postgresql\n      database: cookbook\n      username: kputnam\n      password: secret\n      host: localhost\n\nHere we'll add some stored procedures to the database we described above:\n\n    $ cat example/proc/*.sql | psql -U kputnam -h localhost cookbook\n\nNote the connection is expected to be named `piggly` but you may specify the `-k DATABASE` option to\nuse a different connection name (eg `-k development` in Rails).  See also `example/config/database.yml`.\n\nNow you are ready to recompile and install your stored procedures. This reads the configuration from \n`./config/database.yml` relative to the current working directory.\n\n    $ piggly trace\n    compiling 5 procedures\n    Compiling scramble\n    Compiling scramble\n    Compiling numberedargs\n    Compiling snippets\n    Compiling iterate\n    tracing 5 procedures\n\nThis caches the original version (without instrumentation) in `piggly/cache` so you can restore them\nlater. Piggly will only recompile procedures that have changed in the database since it last\nmade a copy in `piggly/cache`.\n\n*WARNING*: piggly fetches your code from the database and replaces it (in the database) with the\ninstrumented code. If you run `piggly trace` twice consecutively, the second time will cause an error\nbecause you are trying to re-instrument code that has already been instrumented. You need to run\n`piggly untrace` or restore your original stored procedures manually before you can trace them again.\n\nNow you're ready to execute your tests. Make sure your connection is configured to log `RAISE WARNING`\nmessages to a file -- or you can log them to `STDERR` and redirect that to a file. For instance you\nmight run:\n\n    $ ant test 2\u003e messages.txt\n    $ make test 2\u003e messages.txt\n    etc.\n\nTo build the coverage report, have piggly read that file in by executing `piggly report \u003c messages.txt`,\n or `piggly report -f messages.txt`. You don't actually need the intermediate file, you can pipe your\ntest suite directly in like `ant test 2\u003e\u00261 | piggly report`.\n\nOnce the report is built you can open it in `piggly/reports/index.html`.\n\n## Running the Examples\n\n    $ cd piggly\n    $ bundle install\n    $ cat example/README\n    ...\n\n    $ ./example/run-tests\n    compiling 5 procedures\n    Compiling scramble\n    Compiling scramble\n    Compiling numberedargs\n    Compiling snippets\n    Compiling iterate\n    tracing 5 procedures\n    Loaded suite /home/kputnam/wd/piggly/example/test/iterate_test\n    Started\n    ......\n    Finished in 0.199236 seconds.\n\n    6 tests, 6 assertions, 0 failures, 0 errors, 0 skips\n\n    Test run options: --seed 25290\n    clearing previous coverage\n    storing coverage profile\n    creating index\n    creating reports\n    reporting coverage for scramble\n    reporting coverage for scramble\n    reporting coverage for numberedargs\n    reporting coverage for snippets\n    reporting coverage for iterate: +0.0% block, +0.0% branch, +0.0% loop\n    restoring 5 procedures\n    OK, view /home/kputnam/wd/piggly/example/piggly/reports/index.html\n\n    $ ls -alh example/reports/index.html\n    -rw-r--r-- 1 kputnam kputnam 1.4K 2010-04-28 11:21 example/reports/index.html\n\n## Bugs \u0026 Issues\n\nPlease report any issues or feature requests on the [github tracker](http://github.com/kputnam/piggly/issues).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkputnam%2Fpiggly","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkputnam%2Fpiggly","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkputnam%2Fpiggly/lists"}