mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 14:02:26 +01:00
finalize json output & add schema (#118)
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
// +build integration
|
||||
|
||||
package integration
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/anchore/go-testutils"
|
||||
"github.com/anchore/syft/syft"
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
"github.com/anchore/syft/syft/presenter"
|
||||
"github.com/anchore/syft/syft/scope"
|
||||
"github.com/xeipuuv/gojsonschema"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const jsonSchemaExamplesPath = "json-schema/examples"
|
||||
|
||||
func repoRoot(t *testing.T) string {
|
||||
t.Helper()
|
||||
repoRoot, err := exec.Command("git", "rev-parse", "--show-toplevel").Output()
|
||||
if err != nil {
|
||||
t.Fatalf("unable to find repo root dir: %+v", err)
|
||||
}
|
||||
absRepoRoot, err := filepath.Abs(strings.TrimSpace(string(repoRoot)))
|
||||
if err != nil {
|
||||
t.Fatal("unable to get abs path to repo root:", err)
|
||||
}
|
||||
return absRepoRoot
|
||||
}
|
||||
|
||||
func validateAgainstV1Schema(t *testing.T, json string) {
|
||||
fullSchemaPath := path.Join(repoRoot(t), "json-schema", "schema.json")
|
||||
schemaLoader := gojsonschema.NewReferenceLoader(fmt.Sprintf("file://%s", fullSchemaPath))
|
||||
documentLoader := gojsonschema.NewStringLoader(json)
|
||||
|
||||
result, err := gojsonschema.Validate(schemaLoader, documentLoader)
|
||||
if err != nil {
|
||||
t.Fatal("unable to validate json schema:", err.Error())
|
||||
}
|
||||
|
||||
if !result.Valid() {
|
||||
t.Errorf("failed json schema validation:")
|
||||
for _, desc := range result.Errors() {
|
||||
t.Errorf(" - %s\n", desc)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func testJsonSchema(t *testing.T, catalog *pkg.Catalog, theScope *scope.Scope, prefix string) {
|
||||
// make the json output example dir if it does not exist
|
||||
absJsonSchemaExamplesPath := path.Join(repoRoot(t), jsonSchemaExamplesPath)
|
||||
if _, err := os.Stat(absJsonSchemaExamplesPath); os.IsNotExist(err) {
|
||||
os.Mkdir(absJsonSchemaExamplesPath, 0755)
|
||||
}
|
||||
|
||||
output := bytes.NewBufferString("")
|
||||
|
||||
p := presenter.GetPresenter(presenter.JSONPresenter, *theScope, catalog)
|
||||
if p == nil {
|
||||
t.Fatal("unable to get presenter")
|
||||
}
|
||||
|
||||
err := p.Present(output)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to present: %+v", err)
|
||||
}
|
||||
|
||||
// we use the examples dir as a way to use integration tests to drive what valid examples are in case we
|
||||
// want to update the json schema. We do not want to validate the output of the presentation format as the
|
||||
// contents may change regularly, making the integration tests brittle.
|
||||
testFileName := prefix + "_" + path.Base(t.Name()) + ".json"
|
||||
testFilePath := path.Join(absJsonSchemaExamplesPath, testFileName)
|
||||
|
||||
fh, err := os.OpenFile(testFilePath, os.O_WRONLY|os.O_CREATE, 0644)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to open json example path: %+v", err)
|
||||
}
|
||||
_, err = fh.WriteString(output.String())
|
||||
if err != nil {
|
||||
t.Fatalf("unable to write json example: %+v", err)
|
||||
}
|
||||
|
||||
validateAgainstV1Schema(t, output.String())
|
||||
}
|
||||
|
||||
func TestJsonSchemaImg(t *testing.T) {
|
||||
fixtureImageName := "image-pkg-coverage"
|
||||
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
||||
tarPath := testutils.GetFixtureImageTarPath(t, fixtureImageName)
|
||||
defer cleanup()
|
||||
|
||||
catalog, theScope, _, err := syft.Catalog("docker-archive://"+tarPath, scope.AllLayersScope)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to catalog image: %+v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
testJsonSchema(t, catalog, theScope, "img")
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJsonSchemaDirs(t *testing.T) {
|
||||
catalog, theScope, _, err := syft.Catalog("dir://test-fixtures/image-pkg-coverage", scope.AllLayersScope)
|
||||
if err != nil {
|
||||
t.Errorf("unable to create scope from dir: %+v", err)
|
||||
}
|
||||
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
testJsonSchema(t, catalog, theScope, "dir")
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
// +build integration
|
||||
|
||||
package integration
|
||||
|
||||
import "github.com/anchore/syft/syft/pkg"
|
||||
|
||||
var cases = []struct {
|
||||
name string
|
||||
pkgType pkg.Type
|
||||
pkgLanguage pkg.Language
|
||||
pkgInfo map[string]string
|
||||
}{
|
||||
{
|
||||
name: "find rpmdb packages",
|
||||
pkgType: pkg.RpmPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"dive": "0.9.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find dpkg packages",
|
||||
pkgType: pkg.DebPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"apt": "1.8.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find java packages",
|
||||
pkgType: pkg.JavaPkg,
|
||||
pkgLanguage: pkg.Java,
|
||||
pkgInfo: map[string]string{
|
||||
"example-java-app-maven": "0.1.0",
|
||||
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find jenkins plugins",
|
||||
pkgType: pkg.JenkinsPluginPkg,
|
||||
pkgLanguage: pkg.Java,
|
||||
pkgInfo: map[string]string{
|
||||
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python wheel packages",
|
||||
pkgType: pkg.WheelPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"Pygments": "2.6.1",
|
||||
"requests": "2.10.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find javascript npm packages",
|
||||
pkgType: pkg.NpmPkg,
|
||||
pkgLanguage: pkg.JavaScript,
|
||||
pkgInfo: map[string]string{
|
||||
"get-stdin": "8.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find javascript yarn packages",
|
||||
pkgType: pkg.YarnPkg,
|
||||
pkgLanguage: pkg.JavaScript,
|
||||
pkgInfo: map[string]string{
|
||||
"@babel/code-frame": "7.10.4",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python egg packages",
|
||||
pkgType: pkg.EggPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"requests": "2.22.0",
|
||||
"otherpkg": "2.19.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python packages",
|
||||
pkgType: pkg.PythonRequirementsPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"flask": "4.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find bundler packages",
|
||||
pkgType: pkg.BundlerPkg,
|
||||
pkgLanguage: pkg.Ruby,
|
||||
pkgInfo: map[string]string{
|
||||
"actionmailer": "4.1.1",
|
||||
"actionpack": "4.1.1",
|
||||
"actionview": "4.1.1",
|
||||
"activemodel": "4.1.1",
|
||||
"activerecord": "4.1.1",
|
||||
"activesupport": "4.1.1",
|
||||
"arel": "5.0.1.20140414130214",
|
||||
"bootstrap-sass": "3.1.1.1",
|
||||
"builder": "3.2.2",
|
||||
"coffee-rails": "4.0.1",
|
||||
"coffee-script": "2.2.0",
|
||||
"coffee-script-source": "1.7.0",
|
||||
"erubis": "2.7.0",
|
||||
"execjs": "2.0.2",
|
||||
"hike": "1.2.3",
|
||||
"i18n": "0.6.9",
|
||||
"jbuilder": "2.0.7",
|
||||
"jquery-rails": "3.1.0",
|
||||
"json": "1.8.1",
|
||||
"kgio": "2.9.2",
|
||||
"libv8": "3.16.14.3",
|
||||
"mail": "2.5.4",
|
||||
"mime-types": "1.25.1",
|
||||
"minitest": "5.3.4",
|
||||
"multi_json": "1.10.1",
|
||||
"mysql2": "0.3.16",
|
||||
"polyglot": "0.3.4",
|
||||
"rack": "1.5.2",
|
||||
"rack-test": "0.6.2",
|
||||
"rails": "4.1.1",
|
||||
"railties": "4.1.1",
|
||||
"raindrops": "0.13.0",
|
||||
"rake": "10.3.2",
|
||||
"rdoc": "4.1.1",
|
||||
"ref": "1.0.5",
|
||||
"sass": "3.2.19",
|
||||
"sass-rails": "4.0.3",
|
||||
"sdoc": "0.4.0",
|
||||
"spring": "1.1.3",
|
||||
"sprockets": "2.11.0",
|
||||
"sprockets-rails": "2.1.3",
|
||||
"sqlite3": "1.3.9",
|
||||
"therubyracer": "0.12.1",
|
||||
"thor": "0.19.1",
|
||||
"thread_safe": "0.3.3",
|
||||
"tilt": "1.4.1",
|
||||
"treetop": "1.4.15",
|
||||
"turbolinks": "2.2.2",
|
||||
"tzinfo": "1.2.0",
|
||||
"uglifier": "2.5.0",
|
||||
"unicorn": "4.8.3",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
name: "find apkdb packages",
|
||||
pkgType: pkg.ApkPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"musl-utils": "1.1.24-r2",
|
||||
"libc-utils": "0.7.2-r0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find golang modules",
|
||||
pkgType: pkg.GoModulePkg,
|
||||
pkgLanguage: pkg.Go,
|
||||
pkgInfo: map[string]string{
|
||||
"github.com/bmatcuk/doublestar": "v1.3.1",
|
||||
},
|
||||
},
|
||||
}
|
||||
-156
@@ -14,162 +14,6 @@ import (
|
||||
"github.com/anchore/syft/syft/scope"
|
||||
)
|
||||
|
||||
var cases = []struct {
|
||||
name string
|
||||
pkgType pkg.Type
|
||||
pkgLanguage pkg.Language
|
||||
pkgInfo map[string]string
|
||||
}{
|
||||
{
|
||||
name: "find rpmdb packages",
|
||||
pkgType: pkg.RpmPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"dive": "0.9.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find dpkg packages",
|
||||
pkgType: pkg.DebPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"apt": "1.8.2",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find java packages",
|
||||
pkgType: pkg.JavaPkg,
|
||||
pkgLanguage: pkg.Java,
|
||||
pkgInfo: map[string]string{
|
||||
"example-java-app-maven": "0.1.0",
|
||||
"example-jenkins-plugin": "1.0-SNAPSHOT", // the jenkins HPI file has a nested JAR of the same name
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find jenkins plugins",
|
||||
pkgType: pkg.JenkinsPluginPkg,
|
||||
pkgLanguage: pkg.Java,
|
||||
pkgInfo: map[string]string{
|
||||
"example-jenkins-plugin": "1.0-SNAPSHOT",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python wheel packages",
|
||||
pkgType: pkg.WheelPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"Pygments": "2.6.1",
|
||||
"requests": "2.10.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find javascript npm packages",
|
||||
pkgType: pkg.NpmPkg,
|
||||
pkgLanguage: pkg.JavaScript,
|
||||
pkgInfo: map[string]string{
|
||||
"get-stdin": "8.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find javascript yarn packages",
|
||||
pkgType: pkg.YarnPkg,
|
||||
pkgLanguage: pkg.JavaScript,
|
||||
pkgInfo: map[string]string{
|
||||
"@babel/code-frame": "7.10.4",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python egg packages",
|
||||
pkgType: pkg.EggPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"requests": "2.22.0",
|
||||
"otherpkg": "2.19.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find python packages",
|
||||
pkgType: pkg.PythonRequirementsPkg,
|
||||
pkgLanguage: pkg.Python,
|
||||
pkgInfo: map[string]string{
|
||||
"flask": "4.0.0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find bundler packages",
|
||||
pkgType: pkg.BundlerPkg,
|
||||
pkgLanguage: pkg.Ruby,
|
||||
pkgInfo: map[string]string{
|
||||
"actionmailer": "4.1.1",
|
||||
"actionpack": "4.1.1",
|
||||
"actionview": "4.1.1",
|
||||
"activemodel": "4.1.1",
|
||||
"activerecord": "4.1.1",
|
||||
"activesupport": "4.1.1",
|
||||
"arel": "5.0.1.20140414130214",
|
||||
"bootstrap-sass": "3.1.1.1",
|
||||
"builder": "3.2.2",
|
||||
"coffee-rails": "4.0.1",
|
||||
"coffee-script": "2.2.0",
|
||||
"coffee-script-source": "1.7.0",
|
||||
"erubis": "2.7.0",
|
||||
"execjs": "2.0.2",
|
||||
"hike": "1.2.3",
|
||||
"i18n": "0.6.9",
|
||||
"jbuilder": "2.0.7",
|
||||
"jquery-rails": "3.1.0",
|
||||
"json": "1.8.1",
|
||||
"kgio": "2.9.2",
|
||||
"libv8": "3.16.14.3",
|
||||
"mail": "2.5.4",
|
||||
"mime-types": "1.25.1",
|
||||
"minitest": "5.3.4",
|
||||
"multi_json": "1.10.1",
|
||||
"mysql2": "0.3.16",
|
||||
"polyglot": "0.3.4",
|
||||
"rack": "1.5.2",
|
||||
"rack-test": "0.6.2",
|
||||
"rails": "4.1.1",
|
||||
"railties": "4.1.1",
|
||||
"raindrops": "0.13.0",
|
||||
"rake": "10.3.2",
|
||||
"rdoc": "4.1.1",
|
||||
"ref": "1.0.5",
|
||||
"sass": "3.2.19",
|
||||
"sass-rails": "4.0.3",
|
||||
"sdoc": "0.4.0",
|
||||
"spring": "1.1.3",
|
||||
"sprockets": "2.11.0",
|
||||
"sprockets-rails": "2.1.3",
|
||||
"sqlite3": "1.3.9",
|
||||
"therubyracer": "0.12.1",
|
||||
"thor": "0.19.1",
|
||||
"thread_safe": "0.3.3",
|
||||
"tilt": "1.4.1",
|
||||
"treetop": "1.4.15",
|
||||
"turbolinks": "2.2.2",
|
||||
"tzinfo": "1.2.0",
|
||||
"uglifier": "2.5.0",
|
||||
"unicorn": "4.8.3",
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
name: "find apkdb packages",
|
||||
pkgType: pkg.ApkPkg,
|
||||
pkgInfo: map[string]string{
|
||||
"musl-utils": "1.1.24-r2",
|
||||
"libc-utils": "0.7.2-r0",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "find golang modules",
|
||||
pkgType: pkg.GoModulePkg,
|
||||
pkgLanguage: pkg.Go,
|
||||
pkgInfo: map[string]string{
|
||||
"github.com/bmatcuk/doublestar": "v1.3.1",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func TestPkgCoverageImage(t *testing.T) {
|
||||
fixtureImageName := "image-pkg-coverage"
|
||||
_, cleanup := testutils.GetFixtureImage(t, "docker-archive", fixtureImageName)
|
||||
File diff suppressed because one or more lines are too long
@@ -1,256 +0,0 @@
|
||||
[Path: test-fixtures]
|
||||
[actionmailer]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[actionpack]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[actionview]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[activemodel]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[activerecord]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[activesupport]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[arel]
|
||||
Version: 5.0.1.20140414130214
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[bootstrap-sass]
|
||||
Version: 3.1.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[builder]
|
||||
Version: 3.2.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[coffee-rails]
|
||||
Version: 4.0.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[coffee-script]
|
||||
Version: 2.2.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[coffee-script-source]
|
||||
Version: 1.7.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[erubis]
|
||||
Version: 2.7.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[execjs]
|
||||
Version: 2.0.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[hike]
|
||||
Version: 1.2.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[i18n]
|
||||
Version: 0.6.9
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[jbuilder]
|
||||
Version: 2.0.7
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[jquery-rails]
|
||||
Version: 3.1.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[json]
|
||||
Version: 1.8.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[kgio]
|
||||
Version: 2.9.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[libv8]
|
||||
Version: 3.16.14.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[mail]
|
||||
Version: 2.5.4
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[mime-types]
|
||||
Version: 1.25.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[minitest]
|
||||
Version: 5.3.4
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[multi_json]
|
||||
Version: 1.10.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[mysql2]
|
||||
Version: 0.3.16
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[polyglot]
|
||||
Version: 0.3.4
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[rack]
|
||||
Version: 1.5.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[rack-test]
|
||||
Version: 0.6.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[rails]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[railties]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[raindrops]
|
||||
Version: 0.13.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[rake]
|
||||
Version: 10.3.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[rdoc]
|
||||
Version: 4.1.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[ref]
|
||||
Version: 1.0.5
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sass]
|
||||
Version: 3.2.19
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sass-rails]
|
||||
Version: 4.0.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sdoc]
|
||||
Version: 0.4.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[spring]
|
||||
Version: 1.1.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sprockets]
|
||||
Version: 2.11.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sprockets-rails]
|
||||
Version: 2.1.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[sqlite3]
|
||||
Version: 1.3.9
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[therubyracer]
|
||||
Version: 0.12.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[thor]
|
||||
Version: 0.19.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[thread_safe]
|
||||
Version: 0.3.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[tilt]
|
||||
Version: 1.4.1
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[treetop]
|
||||
Version: 1.4.15
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[turbolinks]
|
||||
Version: 2.2.2
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[tzinfo]
|
||||
Version: 1.2.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[uglifier]
|
||||
Version: 2.5.0
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
[unicorn]
|
||||
Version: 4.8.3
|
||||
Type: bundle
|
||||
Found by: bundler-cataloger
|
||||
|
||||
Reference in New Issue
Block a user