{"id":20954336,"url":"https://github.com/scijava/jgo","last_synced_at":"2025-10-09T00:41:39.228Z","repository":{"id":41883294,"uuid":"83717536","full_name":"scijava/jgo","owner":"scijava","description":"Launch Java code from the CLI, installation-free. ☕","archived":false,"fork":false,"pushed_at":"2025-07-20T17:28:20.000Z","size":426,"stargazers_count":82,"open_issues_count":31,"forks_count":16,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-09-24T05:27:55.802Z","etag":null,"topics":["java","launcher","maven","package-manager","python","shell-script"],"latest_commit_sha":null,"homepage":"https://pypi.org/project/jgo/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scijava.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-03-02T19:41:31.000Z","updated_at":"2025-07-20T17:28:23.000Z","dependencies_parsed_at":"2024-06-18T16:47:29.259Z","dependency_job_id":"1c0aab1e-c216-4472-9bc4-d409cdb9bcad","html_url":"https://github.com/scijava/jgo","commit_stats":{"total_commits":293,"total_committers":16,"mean_commits":18.3125,"dds":0.4641638225255973,"last_synced_commit":"fcaf3072a6d42c97acbeac1406e9548bc78d9b14"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/scijava/jgo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fjgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fjgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fjgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fjgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scijava","download_url":"https://codeload.github.com/scijava/jgo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scijava%2Fjgo/sbom","scorecard":{"id":804662,"data":{"date":"2025-08-11","repo":{"name":"github.com/scijava/jgo","commit":"b9c2194040d837d7422c5ea64ce30514313be9e3"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Code-Review","score":1,"reason":"Found 4/27 approved changesets -- score normalized to 1","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":"Maintained","score":7,"reason":"9 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 7","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"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":"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":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","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":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/build.yml:1","Info: no jobLevel write permissions found"],"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":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Info: Possibly incomplete results: error parsing shell code: not a valid arithmetic operator: $: jgo.sh:0","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/scijava/jgo/build.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/build.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/scijava/jgo/build.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:32","Warn: pipCommand not pinned by hash: .github/workflows/build.yml:33","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"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":"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"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":10,"reason":"license file detected","details":["Info: project has a license file: UNLICENSE:0","Info: FSF or OSI recognized license: The Unlicense: UNLICENSE:0"],"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":"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":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 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-23T11:26:56.754Z","repository_id":41883294,"created_at":"2025-08-23T11:26:56.755Z","updated_at":"2025-08-23T11:26:56.755Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279000640,"owners_count":26082879,"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-10-08T02:00:06.501Z","response_time":56,"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":["java","launcher","maven","package-manager","python","shell-script"],"created_at":"2024-11-19T01:14:09.812Z","updated_at":"2025-10-09T00:41:39.207Z","avatar_url":"https://github.com/scijava.png","language":"Python","readme":"[![build status](https://github.com/scijava/jgo/actions/workflows/build.yml/badge.svg)](https://github.com/scijava/jgo/actions/workflows/build.yml)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n# jgo: painless Java component execution\n\n![](https://raw.githubusercontent.com/scijava/jgo/main/jgo.png)\n\n## Summary\n\n[Maven](https://maven.apache.org/) is a great tool. It manages dependencies so\nthat Java projects become reusable \"building blocks\" in a robust way, like\n`pip` for Python, `npm` for JavaScript, `gem` for Ruby, `cpan` for Perl, etc.\nAnd the [Maven Central repository](https://search.maven.org/) contains a\ntremendous wealth of code, ripe for reuse in your own projects.\n\nUnfortunately, Maven provides no easy way to actually __launch code__ from the\nbeautifully managed dependencies stored so lovingly into `~/.m2/repository`.\n\nThis project fills that gap: `jgo` launches Java code. You do not need to\ndownload or install any JARs; you just specify an \"endpoint\" consisting of a\n[Maven artifact](https://stackoverflow.com/a/2487511/1207769) identifier, plus\na main class if needed/desired, and `jgo` uses Maven to obtain and run it.\n\nTo do this, `jgo` builds the local environment on demand, caching it into a\nsubfolder of `~/.jgo`, so that the endpoint's particular dependencies are\navailable in one place.\n\n## Installation\n\nThe `jgo` project began life as a shell script, but was later translated into\nPython, so that tools such as [scyjava](https://github.com/scijava/scyjava)\ncould leverage its environment-building capabilities.\n\nAs such, there are now two implementations from which to choose!\nEach has pros and cons.\n\n### Prerequisites\n\n`jgo` uses `mvn` and `java` for the heavy lifting.\nThe shell script version needs some common utilities (e.g., `cat`).\nIf you are missing anything, the script will tell you.\n\n### The shell script\n\nThe `jgo.sh` shell script requires a POSIX-friendly system. It is known to\nwork on Linux, macOS, [Cygwin](https://www.cygwin.com/), Microsoft's\n[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install),\nand Git BASH from the [Git for Windows](https://git-for-windows.github.io/) project.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eInstalling the shell script\u003c/strong\u003e\u003c/summary\u003e\n\nJust clone this repo and symlink `jgo.sh` into your favorite `bin` directory.\n\nFor example, assuming `~/bin` is on your PATH:\n\n```shell\ncd\ngit clone https://github.com/scijava/jgo\ncd bin\nln -s ../jgo/jgo.sh jgo\njgo --help\n```\n\n\u003c/details\u003e\n\n### The Python module\n\nThe Python version of `jgo` offers a `jgo` console script, as\nwell as a `jgo` module for programmatically creating endpoints.\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eInstalling with pip\u003c/strong\u003e\u003c/summary\u003e\n\n```shell\npip install jgo\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eInstalling with conda\u003c/strong\u003e\u003c/summary\u003e\n\n```shell\nconda install -c conda-forge jgo\n```\n\n\u003c/details\u003e\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eInstalling from source\u003c/strong\u003e\u003c/summary\u003e\n\n```shell\ngit clone https://github.com/scijava/jgo\ncd jgo\n\n# install globally (not recommended unless using a virtual environment)\npip install .\n\n# install into ~/.local (see pip install --help for details)\npip install --user .\n\n# install into $PREFIX\npip install --prefix=$PREFIX .\n\n# install globally in developer mode (hot linked to working copy folder)\npip install -e .\n```\n\n\u003c/details\u003e\n\n## Usage\n\n```\nUsage: jgo [-v] [-u] [-U] [-m] \u003cjvm-args\u003e \u003cendpoint\u003e \u003cmain-args\u003e\n\n  -v          : verbose mode flag\n  -u          : update/regenerate cached environment\n  -U          : force update from remote Maven repositories (implies -u)\n  -m          : use endpoints for dependency management (see \"Pitfalls\" below)\n  \u003cjvm-args\u003e  : any list of arguments to the JVM\n  \u003cendpoint\u003e  : the artifact(s) + main class to execute\n  \u003cmain-args\u003e : any list of arguments to the main class\n\nThe endpoint should have one of the following formats:\n\n- groupId:artifactId\n- groupId:artifactId:version\n- groupId:artifactId:mainClass\n- groupId:artifactId:version:mainClass\n- groupId:artifactId:version:classifier:mainClass\n\nIf version is omitted, then RELEASE is used.\nIf mainClass is omitted, it is auto-detected.\nYou can also write part of a class beginning with an @ sign,\nand it will be auto-completed.\n\nMultiple artifacts can be concatenated with pluses,\nand all of them will be included on the classpath.\nHowever, you should not specify multiple main classes.\n```\n\n### Examples\n\n| Program                      | Command                                                                             |\n|-----------------------------:|:------------------------------------------------------------------------------------|\n| Jython REPL                  | `jgo org.python:jython-standalone`                                                  |\n| JRuby eval                   | `echo \"puts 'Hello Ruby'\" \\| jgo org.jruby:jruby-complete:@jruby.Main`              |\n| Groovy REPL                  | `jgo org.codehaus.groovy:groovy-groovysh:@shell.Main+commons-cli:commons-cli:1.3.1` |\n\nNote the usage of the `+` syntax as needed to append elements to the classpath.\n\nIf you add\n`scijava.public = https://maven.scijava.org/content/groups/public`\nto the\n`[repositories]` section of your `.jgorc`\n(see [Repositories](#repositories) below),\nyou can also try:\n\n| Program                      | Command                                                                             |\n|-----------------------------:|:------------------------------------------------------------------------------------|\n| SciJava REPL with JRuby      | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-jruby`            |\n| SciJava REPL with Jython     | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-jython`           |\n| SciJava REPL with Groovy     | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-groovy`           |\n| SciJava REPL with Clojure    | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-clojure`          |\n| SciJava REPL with JavaScript | `jgo org.scijava:scijava-common:@ScriptREPL+org.scijava:scripting-javascript`       |\n\n### FAQ\n\n* __Is it fast?__\n  Endpoints are synthesized in a local cache under `~/.jgo`.\n  So invoking the same endpoint a second time is really quick.\n* __What does \"no installation\" mean?__\n  Classpath elements are [hard-linked](https://en.wikipedia.org/wiki/Hard_link)\n  into `~/.jgo` from `~/.m2/repository` rather than copied, so the `~/.jgo`\n  folder has a tiny footprint even if you execute lots of different endpoints.\n* __What if an endpoint has a new version?__\n  Pass the `-U` flag to `jgo` to rebuild the endpoint.\n  Note that unlike `mvn`, though, `jgo` does not check for updates otherwise.\n\n### Configuration\n\nYou can configure the behavior of `jgo` using the `~/.jgorc` file.\n\n#### Repositories\n\nYou can define additional remote Maven repositories,\nfrom which artifacts will be retrieved. E.g.:\n\n```ini\n[repositories]\nscijava.public = https://maven.scijava.org/content/groups/public\n```\n\nIf you need more control over where artifacts come from—for example, if you\nwant to use your own remote Maven repository as a mirror of Maven Central—you\ncan do it using Maven's usual `~/.m2/settings.xml`; see [Using Mirrors for\nRepositories](https://maven.apache.org/guides/mini/guide-mirror-settings.html).\n\nYou can also use the `-r` flag to pass additional repositories to individual\ninvocations of jgo.\n\n#### Shortcuts\n\nYou can define shortcuts for launching commonly used programs:\n\n```ini\n[shortcuts]\nrepl = imagej:org.scijava.script.ScriptREPL\nimagej = net.imagej:imagej\nfiji = sc.fiji:fiji:LATEST\nscifio = io.scif:scifio-cli\n```\n\nShortcuts are substituted verbatim from the beginning of the endpoint,\nsingle-pass in the order they are defined. So e.g. now you can run:\n```shell\njgo repl\n```\nNote that with the `repl` shortcut above, the main class\n(`org.scijava.script.ScriptREPL`) comes from a _different_ artifact than\nthe toplevel artifact (`net.imagej:imagej`). This is intentional, so that\nall of [ImageJ](https://imagej.net/), including all of the various SciJava\n`scripting-\u003cfoo\u003e` plugins, is included in the classpath of the REPL.\n\n#### Settings\n\nThere are a few configurable settings:\n\n```ini\n[settings]\nm2Repo = /path/to/.m2Repo (default ~/.m2/repository)\ncacheDir = /path/to/.jgo (default ~/.jgo)\nlinks = soft (options: hard, soft, none; default hard)\n```\nNote that the `jgo` cache dir can also be set via the `JGO_CACHE_DIR` environment\nvariable when using **Python** `jgo`. The precedence of reading the cache dir, from\nhighest to lowest:\n  - `JGO_CACHE_DIR` environment variable\n  - `cacheDir` in `settings` sections in `~/.jgorc`\n  - default to `~/.jgo`\n\n### Pitfalls\n\n#### Dependency management\n\nMaven has a feature whereby a project can override the versions of transitive\n(a.k.a. inherited) dependencies, via a `\u003cdependencyManagement\u003e` configuration.\nThe problem is: a library may then believe it depends on components at\nparticular versions as defined by its `\u003cdependencyManagement\u003e`, but downstream\nprojects which depend on that library will resolve to different versions.\nSee [this SO thread](https://stackoverflow.com/q/45041888/1207769) and\n[this gist](https://gist.github.com/ctrueden/d058330c8a3687317806ce8cc18332c3)\nfor full details.\n\nTo work around this issue, you can pass `-m` to jgo, which\ncauses it to add all endpoints to the synthesized POM's\n`\u003cdependencyManagement\u003e` section using\n[import scope](https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Importing_Dependencies).\nBy doing this, the versions of transitive dependencies used in the synthesized\nproject should more precisely match those of each endpoint itself—although in\nthe case of multiple endpoints concatenated via the `+` operator with\nconflicting dependency management, the earlier endpoints will win because they\nwill be declared earlier in the POM. See also\n[issue #9](https://github.com/scijava/jgo/issues/9) in the jgo issue tracker.\n\n## Development\n\n### Code style\n\n`jgo` uses [`black`](https://github.com/psf/black) for its code style.\n\nAfter `pip install tox`, you can lint the code with:\n\n```shell\ntox -e lint\n```\n\n## Alternatives\n\n* [JBang](https://github.com/jbangdev/jbang)\n* [mvnx](https://github.com/mvnx/mvnx)\n* [JPM4J](https://github.com/jpm4j) (discontinued)\n* [Mop](https://github.com/chirino/mop) (unmaintained)\n* [marun](https://github.com/nishemon/marun) (unmaintained, Python 2 only)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscijava%2Fjgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscijava%2Fjgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscijava%2Fjgo/lists"}