nt-fingerprint 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.github/workflows/test.yml +34 -0
- data/.gitignore +9 -0
- data/.rspec +1 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +0 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +5 -0
- data/LICENSE +29 -0
- data/Makefile +12 -0
- data/README.md +53 -0
- data/Rakefile +4 -0
- data/go/build/libfp-darwin-10.6-amd64.dylib +0 -0
- data/go/build/libfp-darwin-10.6-amd64.h +76 -0
- data/go/build/libfp-linux-amd64.h +76 -0
- data/go/build/libfp-linux-amd64.so +0 -0
- data/go/go.mod +5 -0
- data/go/go.sum +2 -0
- data/go/libfp.go +14 -0
- data/lib/nt/fingerprint.rb +4 -0
- data/lib/nt/fingerprint/fingerprint.rb +24 -0
- data/lib/nt/fingerprint/version.rb +7 -0
- data/nt-fingerprint.gemspec +33 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 9def9ac1a0781ac26a8de4ec3c045419d32b04914d9017b24b24bc05406eff69
|
4
|
+
data.tar.gz: e8e53e0a6378ab8153eefecf1f837a73bb2472e77f6761f65ef6eda365740165
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: '08462d0f676c1ffee6d223b90c466b065db3e4923c808d4d65d784ade79623c19a64a49326bedc806e23d6d818b66594754305dfd0bcb68500353202b31c213e'
|
7
|
+
data.tar.gz: ee10cb0ad7700e195fe5a692be2b5c8a4e72316cf740748a1456fc69858cf272684e8fd58cd519e1bac4e17771a6af08a8361b1f2c1a3800e18d9935571ae9e5
|
@@ -0,0 +1,34 @@
|
|
1
|
+
name: test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
workflow_dispatch:
|
9
|
+
|
10
|
+
defaults:
|
11
|
+
run:
|
12
|
+
shell: bash
|
13
|
+
|
14
|
+
jobs:
|
15
|
+
run_rspec:
|
16
|
+
name: Run Rspec on ${{ matrix.os }} with ${{ matrix.ruby-version }}
|
17
|
+
runs-on: ${{ matrix.os }}
|
18
|
+
strategy:
|
19
|
+
matrix:
|
20
|
+
os: [ubuntu-latest, macos-latest]
|
21
|
+
ruby-version: ['2.7', '3.0']
|
22
|
+
|
23
|
+
steps:
|
24
|
+
- uses: actions/checkout@v2
|
25
|
+
- name: Set up Ruby
|
26
|
+
uses: ruby/setup-ruby@v1
|
27
|
+
with:
|
28
|
+
ruby-version: ${{ matrix.ruby-version }}
|
29
|
+
bundler-cache: true
|
30
|
+
- name: Run RSpec
|
31
|
+
run: |
|
32
|
+
gem install bundler
|
33
|
+
bundle install --jobs 4 --retry 3
|
34
|
+
bundle exec rspec
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
File without changes
|
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
BSD 3-Clause License
|
2
|
+
|
3
|
+
Copyright (c) 2021, Nayuta Yanagisawa
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
8
|
+
|
9
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
10
|
+
list of conditions and the following disclaimer.
|
11
|
+
|
12
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
14
|
+
and/or other materials provided with the distribution.
|
15
|
+
|
16
|
+
3. Neither the name of the copyright holder nor the names of its
|
17
|
+
contributors may be used to endorse or promote products derived from
|
18
|
+
this software without specific prior written permission.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/Makefile
ADDED
data/README.md
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
# nt-fingerprint
|
2
|
+
|
3
|
+

|
4
|
+
|
5
|
+
## Synopsis
|
6
|
+
|
7
|
+
nt-fingerprint is a Ruby gem for converting queries into fingerprints.
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
require 'nt/fingerprint'
|
11
|
+
|
12
|
+
class Sample
|
13
|
+
include Nt::Fingerprint
|
14
|
+
end
|
15
|
+
|
16
|
+
puts Sample.new.fingerprint("SELECT a, b, 'c' FROM t WEHERE a = 1 AND b IN (1, 2, 3)")
|
17
|
+
# => select a, b, ? from t wehere a = ? and b in(?+)
|
18
|
+
```
|
19
|
+
|
20
|
+
nt-fingerprint exposes a single method `fingerprint`. What the method does is just calling a function `query.Fingerprint` of [percona/go-mysql](https://github.com/percona/go-mysql) via FFI. Thus, the behavior of `fingerprint` completely follows that of `query.Fingerprint`. We quote the description of `query.Fingerprint` from the [documentation](https://pkg.go.dev/github.com/percona/go-mysql@v0.0.0-20200630114833-b77f37c0bfa2/query#Fingerprint) of go-mysql.
|
21
|
+
|
22
|
+
> ```
|
23
|
+
> func Fingerprint(q string) string
|
24
|
+
> ```
|
25
|
+
> Fingerprint returns the canonical form of q. The primary transformations are:
|
26
|
+
> ```
|
27
|
+
> - Replace values with ?
|
28
|
+
> - Collapse whitespace
|
29
|
+
> - Remove comments
|
30
|
+
> - Lowercase everything
|
31
|
+
> ```
|
32
|
+
> Additional trasnformations are performed which change the syntax of the original query without affecting its performance characteristics. For example, "ORDER BY col ASC" is the same as "ORDER BY col", so "ASC" in the fingerprint is removed.
|
33
|
+
|
34
|
+
## Examples
|
35
|
+
|
36
|
+
A typical use case of nt-fingerprint is query logging. Using nt-fingerprint, one can exclude sensitive information from queries. This makes it possible to log production queries while maintaining security.
|
37
|
+
|
38
|
+
For example, one can capture arbitrary ActiveRecord queries by combining [Arproxy](https://github.com/cookpad/arproxy) and nt-fingerprint.
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
class QueryLogger < Arproxy::Base
|
42
|
+
include Nt::Fingerprint
|
43
|
+
|
44
|
+
def execute(sql, name=nil)
|
45
|
+
Rails.logger.info(fingerprint(sql))
|
46
|
+
super(sql, name)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
Arproxy.configure do |config|
|
51
|
+
config.use QueryLogger
|
52
|
+
end
|
53
|
+
```
|
data/Rakefile
ADDED
Binary file
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
2
|
+
|
3
|
+
/* package github.com/nayuta-yanagisawa/nt-fingerprint/go */
|
4
|
+
|
5
|
+
|
6
|
+
#line 1 "cgo-builtin-export-prolog"
|
7
|
+
|
8
|
+
#include <stddef.h> /* for ptrdiff_t below */
|
9
|
+
|
10
|
+
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
11
|
+
#define GO_CGO_EXPORT_PROLOGUE_H
|
12
|
+
|
13
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
14
|
+
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#endif
|
18
|
+
|
19
|
+
/* Start of preamble from import "C" comments. */
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
/* End of preamble from import "C" comments. */
|
25
|
+
|
26
|
+
|
27
|
+
/* Start of boilerplate cgo prologue. */
|
28
|
+
#line 1 "cgo-gcc-export-header-prolog"
|
29
|
+
|
30
|
+
#ifndef GO_CGO_PROLOGUE_H
|
31
|
+
#define GO_CGO_PROLOGUE_H
|
32
|
+
|
33
|
+
typedef signed char GoInt8;
|
34
|
+
typedef unsigned char GoUint8;
|
35
|
+
typedef short GoInt16;
|
36
|
+
typedef unsigned short GoUint16;
|
37
|
+
typedef int GoInt32;
|
38
|
+
typedef unsigned int GoUint32;
|
39
|
+
typedef long long GoInt64;
|
40
|
+
typedef unsigned long long GoUint64;
|
41
|
+
typedef GoInt64 GoInt;
|
42
|
+
typedef GoUint64 GoUint;
|
43
|
+
typedef __SIZE_TYPE__ GoUintptr;
|
44
|
+
typedef float GoFloat32;
|
45
|
+
typedef double GoFloat64;
|
46
|
+
typedef float _Complex GoComplex64;
|
47
|
+
typedef double _Complex GoComplex128;
|
48
|
+
|
49
|
+
/*
|
50
|
+
static assertion to make sure the file is being used on architecture
|
51
|
+
at least with matching size of GoInt.
|
52
|
+
*/
|
53
|
+
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
54
|
+
|
55
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
56
|
+
typedef _GoString_ GoString;
|
57
|
+
#endif
|
58
|
+
typedef void *GoMap;
|
59
|
+
typedef void *GoChan;
|
60
|
+
typedef struct { void *t; void *v; } GoInterface;
|
61
|
+
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
62
|
+
|
63
|
+
#endif
|
64
|
+
|
65
|
+
/* End of boilerplate cgo prologue. */
|
66
|
+
|
67
|
+
#ifdef __cplusplus
|
68
|
+
extern "C" {
|
69
|
+
#endif
|
70
|
+
|
71
|
+
|
72
|
+
extern char* fingerprint(char* p0);
|
73
|
+
|
74
|
+
#ifdef __cplusplus
|
75
|
+
}
|
76
|
+
#endif
|
@@ -0,0 +1,76 @@
|
|
1
|
+
/* Code generated by cmd/cgo; DO NOT EDIT. */
|
2
|
+
|
3
|
+
/* package github.com/nayuta-yanagisawa/nt-fingerprint/go */
|
4
|
+
|
5
|
+
|
6
|
+
#line 1 "cgo-builtin-export-prolog"
|
7
|
+
|
8
|
+
#include <stddef.h> /* for ptrdiff_t below */
|
9
|
+
|
10
|
+
#ifndef GO_CGO_EXPORT_PROLOGUE_H
|
11
|
+
#define GO_CGO_EXPORT_PROLOGUE_H
|
12
|
+
|
13
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
14
|
+
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
|
15
|
+
#endif
|
16
|
+
|
17
|
+
#endif
|
18
|
+
|
19
|
+
/* Start of preamble from import "C" comments. */
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
/* End of preamble from import "C" comments. */
|
25
|
+
|
26
|
+
|
27
|
+
/* Start of boilerplate cgo prologue. */
|
28
|
+
#line 1 "cgo-gcc-export-header-prolog"
|
29
|
+
|
30
|
+
#ifndef GO_CGO_PROLOGUE_H
|
31
|
+
#define GO_CGO_PROLOGUE_H
|
32
|
+
|
33
|
+
typedef signed char GoInt8;
|
34
|
+
typedef unsigned char GoUint8;
|
35
|
+
typedef short GoInt16;
|
36
|
+
typedef unsigned short GoUint16;
|
37
|
+
typedef int GoInt32;
|
38
|
+
typedef unsigned int GoUint32;
|
39
|
+
typedef long long GoInt64;
|
40
|
+
typedef unsigned long long GoUint64;
|
41
|
+
typedef GoInt64 GoInt;
|
42
|
+
typedef GoUint64 GoUint;
|
43
|
+
typedef __SIZE_TYPE__ GoUintptr;
|
44
|
+
typedef float GoFloat32;
|
45
|
+
typedef double GoFloat64;
|
46
|
+
typedef float _Complex GoComplex64;
|
47
|
+
typedef double _Complex GoComplex128;
|
48
|
+
|
49
|
+
/*
|
50
|
+
static assertion to make sure the file is being used on architecture
|
51
|
+
at least with matching size of GoInt.
|
52
|
+
*/
|
53
|
+
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
|
54
|
+
|
55
|
+
#ifndef GO_CGO_GOSTRING_TYPEDEF
|
56
|
+
typedef _GoString_ GoString;
|
57
|
+
#endif
|
58
|
+
typedef void *GoMap;
|
59
|
+
typedef void *GoChan;
|
60
|
+
typedef struct { void *t; void *v; } GoInterface;
|
61
|
+
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
62
|
+
|
63
|
+
#endif
|
64
|
+
|
65
|
+
/* End of boilerplate cgo prologue. */
|
66
|
+
|
67
|
+
#ifdef __cplusplus
|
68
|
+
extern "C" {
|
69
|
+
#endif
|
70
|
+
|
71
|
+
|
72
|
+
extern char* fingerprint(char* p0);
|
73
|
+
|
74
|
+
#ifdef __cplusplus
|
75
|
+
}
|
76
|
+
#endif
|
Binary file
|
data/go/go.mod
ADDED
data/go/go.sum
ADDED
data/go/libfp.go
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'ffi'
|
4
|
+
|
5
|
+
module Nt
|
6
|
+
# Fingerprint converts queries to fingerprints.
|
7
|
+
module Fingerprint
|
8
|
+
extend FFI::Library
|
9
|
+
|
10
|
+
platform = `uname -sm`
|
11
|
+
|
12
|
+
file = case platform
|
13
|
+
when /^Linux.*64/
|
14
|
+
'libfp-linux-amd64.so'
|
15
|
+
when /^Darwin.*64/
|
16
|
+
'libfp-darwin-10.6-amd64.dylib'
|
17
|
+
else
|
18
|
+
abort 'nt-fingerprint does not support your platform.'
|
19
|
+
end
|
20
|
+
|
21
|
+
ffi_lib File.expand_path("../../../go/build/#{file}", __dir__)
|
22
|
+
attach_function :fingerprint, [:string], :string
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'lib/nt/fingerprint/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'nt-fingerprint'
|
7
|
+
spec.version = Nt::Fingerprint::VERSION
|
8
|
+
spec.authors = ['Nayuta Yanagisawa']
|
9
|
+
spec.email = ['nayuta.yanagisawa@hey.com']
|
10
|
+
|
11
|
+
spec.summary = 'nt-fingerprint convert queries into fingerprints.'
|
12
|
+
spec.description = spec.summary
|
13
|
+
spec.homepage = 'https://github.com/nayuta-yanagisawa/nt-fingerprint'
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
|
15
|
+
|
16
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
17
|
+
spec.metadata['source_code_uri'] = spec.homepage
|
18
|
+
spec.metadata['changelog_uri'] = spec.homepage
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
spec.bindir = 'exe'
|
26
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
|
29
|
+
spec.add_dependency 'ffi'
|
30
|
+
spec.add_development_dependency 'rspec'
|
31
|
+
spec.add_development_dependency 'rubocop'
|
32
|
+
spec.add_development_dependency 'rake'
|
33
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nt-fingerprint
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nayuta Yanagisawa
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2021-02-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: ffi
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: nt-fingerprint convert queries into fingerprints.
|
70
|
+
email:
|
71
|
+
- nayuta.yanagisawa@hey.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".github/workflows/test.yml"
|
77
|
+
- ".gitignore"
|
78
|
+
- ".rspec"
|
79
|
+
- ".rubocop.yml"
|
80
|
+
- ".rubocop_todo.yml"
|
81
|
+
- CHANGELOG.md
|
82
|
+
- Gemfile
|
83
|
+
- LICENSE
|
84
|
+
- Makefile
|
85
|
+
- README.md
|
86
|
+
- Rakefile
|
87
|
+
- go/build/libfp-darwin-10.6-amd64.dylib
|
88
|
+
- go/build/libfp-darwin-10.6-amd64.h
|
89
|
+
- go/build/libfp-linux-amd64.h
|
90
|
+
- go/build/libfp-linux-amd64.so
|
91
|
+
- go/go.mod
|
92
|
+
- go/go.sum
|
93
|
+
- go/libfp.go
|
94
|
+
- lib/nt/fingerprint.rb
|
95
|
+
- lib/nt/fingerprint/fingerprint.rb
|
96
|
+
- lib/nt/fingerprint/version.rb
|
97
|
+
- nt-fingerprint.gemspec
|
98
|
+
homepage: https://github.com/nayuta-yanagisawa/nt-fingerprint
|
99
|
+
licenses: []
|
100
|
+
metadata:
|
101
|
+
homepage_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
|
102
|
+
source_code_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
|
103
|
+
changelog_uri: https://github.com/nayuta-yanagisawa/nt-fingerprint
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 2.5.0
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubygems_version: 3.1.4
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: nt-fingerprint convert queries into fingerprints.
|
123
|
+
test_files: []
|