kitkat 0.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fbdbb6ec1c0293541eed2e6d3227dd23157f6de455499df55d5bc32f6044c025
4
+ data.tar.gz: 2c02ad2202530ef1d4d2201711bc4dcf18ef1cfeb3543d3b54756b5238cc3be3
5
+ SHA512:
6
+ metadata.gz: bc533656a79f62e7f1ab832166035c24ad2d614e090b4fec5a08a5b5c4218c987aab94437141870fb02931330785819b467034aa437b5be55fedae37c2c90c54
7
+ data.tar.gz: af88084f7c99abcd4c141d419b11628b74178615acf959b667f7d66b1c5881d32e3f64946fb2765c2045094226b28cc8ac0ebb463d2e06744703c05dd3a2429f
data/.editorconfig ADDED
@@ -0,0 +1,8 @@
1
+ # See http://editorconfig.org/
2
+
3
+ [*]
4
+ trim_trailing_whitespace = true
5
+ indent_style = space
6
+ indent_size = 2
7
+ insert_final_newline = true
8
+ end_of_line = lf
@@ -0,0 +1,31 @@
1
+ name: Ruby
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ pull_request:
7
+ branches: [ main ]
8
+
9
+ jobs:
10
+ verify:
11
+ runs-on: ubuntu-latest
12
+ strategy:
13
+ matrix:
14
+ ruby-version: ['2.6', '2.7', '3.0']
15
+
16
+ steps:
17
+ - uses: actions/checkout@v2
18
+ - name: Set up Ruby
19
+ # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
20
+ # change this to (see https://github.com/ruby/setup-ruby#versioning):
21
+ # uses: ruby/setup-ruby@v1
22
+ uses: ruby/setup-ruby@473e4d8fe5dd94ee328fdfca9f8c9c7afc9dae5e
23
+ with:
24
+ ruby-version: ${{ matrix.ruby-version }}
25
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
26
+ - name: Lint
27
+ run: bin/rubocop
28
+ - name: Test
29
+ run: bin/rspec spec --format documentation
30
+ - name: Dependency Audit
31
+ run: bin/bundler-audit check --update
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ .DS_Store
2
+ *.gem
3
+ /tmp
4
+ /coverage
5
+ Gemfile.lock
6
+ /pkg
7
+ kitkat.db
data/.rubocop.yml ADDED
@@ -0,0 +1,9 @@
1
+ AllCops:
2
+ NewCops: enable
3
+ TargetRubyVersion: 2.6
4
+ Exclude:
5
+ - bin/*
6
+ - vendor/bundle/**/*
7
+
8
+ Metrics/MethodLength:
9
+ Max: 20
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 2.6.6
@@ -0,0 +1,73 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported. All complaints will be reviewed and investigated and will result in a response that
59
+ is deemed necessary and appropriate to the circumstances. The project team is
60
+ obligated to maintain confidentiality with regard to the reporter of an incident.
61
+ Further details of specific enforcement policies may be posted separately.
62
+
63
+ Project maintainers who do not follow or enforce the Code of Conduct in good
64
+ faith may face temporary or permanent repercussions as determined by other
65
+ members of the project's leadership.
66
+
67
+ ## Attribution
68
+
69
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
70
+ available at [http://contributor-covenant.org/version/1/4][version]
71
+
72
+ [homepage]: http://contributor-covenant.org
73
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ guard :rspec, cmd: 'DISABLE_SIMPLECOV=true bin/rspec --format=documentation' do
4
+ require 'guard/rspec/dsl'
5
+ dsl = Guard::RSpec::Dsl.new(self)
6
+
7
+ # RSpec files
8
+ rspec = dsl.rspec
9
+ watch(rspec.spec_helper) { rspec.spec_dir }
10
+ watch(rspec.spec_support) { rspec.spec_dir }
11
+ watch(rspec.spec_files)
12
+
13
+ # Ruby files
14
+ ruby = dsl.ruby
15
+ dsl.watch_spec_files_for(ruby.lib_files)
16
+ end
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ # Kitkat
2
+
3
+ #### File/Metadata Database Populator
4
+
5
+ [![Gem Version](https://badge.fury.io/rb/kitkat.svg)](https://badge.fury.io/rb/kitkat) [![Ruby Gem CI](https://github.com/mattruggio/kitkat/actions/workflows/rubygem.yml/badge.svg)](https://github.com/mattruggio/kitkat/actions/workflows/rubygem.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ I had a need to recursively enumerate a directory and load the paths, and some metadata about the files, into a SQLite file.
8
+
9
+ ## Installation
10
+
11
+ To install through Rubygems:
12
+
13
+ ````
14
+ gem install kitkat
15
+ ````
16
+
17
+ You can also add this to your Gemfile using:
18
+
19
+ ````
20
+ bundle add kitkat
21
+ ````
22
+
23
+ ## Usage
24
+
25
+ ### Executable
26
+
27
+ This library ships with an executable: `exe/kitkat`. Simply run this from your shell:
28
+
29
+ ````zsh
30
+ exe/kitkat <path> <database>
31
+ ````
32
+
33
+ For Example: `bin/kitkat some_directory some_directory_contents.db`. This will recursively scan the relative path at: `some_directory` and list all its contents in a SQLite database file relatively located at: `some_directory_contents.db`.
34
+
35
+ Note: database positional argument is optional. If it is not supplied then it will default to: `kitkat.db`
36
+
37
+ ### Ruby API
38
+
39
+ You can also include this gem and use directly through code:
40
+
41
+ ```ruby
42
+ Kitkat.crawl(db: 'some_directory_contents.db', path: 'some_directory')
43
+ ```
44
+
45
+ The Ruby code above is functionally equivalent to running the executable script above.
46
+
47
+ ## Contributing
48
+
49
+ ### Development Environment Configuration
50
+
51
+ Basic steps to take to get this repository compiling:
52
+
53
+ 1. Install [Ruby](https://www.ruby-lang.org/en/documentation/installation/) (check kitkat.gemspec for versions supported)
54
+ 2. Install bundler (gem install bundler)
55
+ 3. Clone the repository (git clone git@github.com:mattruggio/kitkat.git)
56
+ 4. Navigate to the root folder (cd kitkat)
57
+ 5. Install dependencies (bundle)
58
+
59
+ ### Running Tests
60
+
61
+ To execute the test suite run:
62
+
63
+ ````zsh
64
+ bin/rspec spec --format documentation
65
+ ````
66
+
67
+ Alternatively, you can have Guard watch for changes:
68
+
69
+ ````zsh
70
+ bin/guard
71
+ ````
72
+
73
+ Also, do not forget to run Rubocop:
74
+
75
+ ````zsh
76
+ bin/rubocop
77
+ ````
78
+
79
+ And auditing the dependencies:
80
+
81
+ ````zsh
82
+ bin/bundler-audit check --update
83
+ ````
84
+
85
+ ### Publishing
86
+
87
+ Note: ensure you have proper authorization before trying to publish new versions.
88
+
89
+ After code changes have successfully gone through the Pull Request review process then the following steps should be followed for publishing new versions:
90
+
91
+ 1. Merge Pull Request into main
92
+ 2. Update `version.rb` using [semantic versioning](https://semver.org/)
93
+ 3. Install dependencies: `bundle`
94
+ 4. Update `CHANGELOG.md` with release notes
95
+ 5. Commit & push main to remote and ensure CI builds main successfully
96
+ 6. Run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
97
+
98
+ ## Code of Conduct
99
+
100
+ Everyone interacting in this codebase, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/mattruggio/kitkat/blob/main/CODE_OF_CONDUCT.md).
101
+
102
+ ## License
103
+
104
+ This project is MIT Licensed.
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop/rake_task'
6
+
7
+ RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
9
+
10
+ task default: %i[rubocop spec]
data/bin/_guard-core ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application '_guard-core' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("guard", "_guard-core")
data/bin/bundle-audit ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundle-audit' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("bundler-audit", "bundle-audit")
data/bin/bundler-audit ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'bundler-audit' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("bundler-audit", "bundler-audit")
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'kitkat'
6
+ require 'pry'
7
+
8
+ Pry.start
data/bin/guard ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'guard' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("guard", "guard")
data/bin/rake ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rake' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rake", "rake")
data/bin/rspec ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rspec' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rspec-core", "rspec")
data/bin/rubocop ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ #
5
+ # This file was generated by Bundler.
6
+ #
7
+ # The application 'rubocop' is installed as part of a gem, and
8
+ # this file is here to facilitate running it.
9
+ #
10
+
11
+ require "pathname"
12
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
13
+ Pathname.new(__FILE__).realpath)
14
+
15
+ bundle_binstub = File.expand_path("../bundle", __FILE__)
16
+
17
+ if File.file?(bundle_binstub)
18
+ if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
19
+ load(bundle_binstub)
20
+ else
21
+ abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
22
+ Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
23
+ end
24
+ end
25
+
26
+ require "rubygems"
27
+ require "bundler/setup"
28
+
29
+ load Gem.bin_path("rubocop", "rubocop")
data/exe/kitkat ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'kitkat'
6
+
7
+ path = ARGV[0].to_s
8
+ db = ARGV[1].to_s.empty? ? 'kitkat.db' : ARGV[1].to_s
9
+
10
+ Kitkat.crawl(db: db, path: path)
data/kitkat.gemspec ADDED
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require './lib/kitkat/version'
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'kitkat'
7
+ s.version = Kitkat::VERSION
8
+ s.summary = 'File/Metadata Database Populator'
9
+
10
+ s.description = <<-DESCRIPTION
11
+ Small library that can populate a SQLite database with the recursive list of all files and their respective metadata.
12
+ DESCRIPTION
13
+
14
+ s.authors = ['Matthew Ruggio']
15
+ s.email = ['mattruggio@icloud.com']
16
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
17
+ s.bindir = 'exe'
18
+ s.executables = %w[kitkat]
19
+ s.license = 'MIT'
20
+ s.homepage = 'https://github.com/mattruggio/kitkat'
21
+ s.metadata = {
22
+ 'bug_tracker_uri' => 'https://github.com/mattruggio/kitkat/issues',
23
+ 'changelog_uri' => 'https://github.com/mattruggio/kitkat/blob/main/CHANGELOG.md',
24
+ 'documentation_uri' => 'https://www.rubydoc.info/gems/kitkat',
25
+ 'homepage_uri' => s.homepage,
26
+ 'source_code_uri' => s.homepage,
27
+ 'rubygems_mfa_required' => 'true'
28
+ }
29
+
30
+ s.required_ruby_version = '>= 2.6'
31
+
32
+ s.add_dependency('sqlite3')
33
+
34
+ s.add_development_dependency('bundler-audit')
35
+ s.add_development_dependency('guard-rspec')
36
+ s.add_development_dependency('pry')
37
+ s.add_development_dependency('rake')
38
+ s.add_development_dependency('rspec')
39
+ s.add_development_dependency('rubocop')
40
+ s.add_development_dependency('rubocop-rake')
41
+ s.add_development_dependency('rubocop-rspec')
42
+ s.add_development_dependency('simplecov')
43
+ s.add_development_dependency('simplecov-console')
44
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitkat
4
+ # Database-level operations.
5
+ class Database
6
+ def initialize(path)
7
+ @connection = SQLite3::Database.new(path)
8
+
9
+ load_schema
10
+
11
+ freeze
12
+ end
13
+
14
+ def insert(file_info)
15
+ connection.execute(
16
+ sql_statement,
17
+ file_info.relative_path,
18
+ file_info.mime_type,
19
+ file_info.mime_subtype,
20
+ file_info.bytesize,
21
+ file_info.last_modified_at.to_s,
22
+ file_info.digest,
23
+ Time.now.utc.to_s
24
+ )
25
+
26
+ self
27
+ end
28
+
29
+ private
30
+
31
+ attr_reader :connection
32
+
33
+ def sql_statement
34
+ 'INSERT OR IGNORE INTO files VALUES (?, ?, ?, ?, ?, ?, ?)'
35
+ end
36
+
37
+ def load_schema
38
+ connection.execute <<-SQL
39
+ CREATE TABLE IF NOT EXISTS files (
40
+ path varchar NOT NULL,
41
+ mime_type varchar NOT NULL,
42
+ mime_subtype varchar NOT NULL,
43
+ bytesize integer NOT NULL,
44
+ last_modified_at datetime,
45
+ digest varchar NOT NULL,
46
+ created_at datetime NOT NULL
47
+ );
48
+ SQL
49
+
50
+ connection.execute <<-SQL
51
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_files_path ON files (path);
52
+ SQL
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitkat
4
+ # File-level operations.
5
+ class FileInfo
6
+ BLANK = ''
7
+ MIME_TYPE_SEPARATOR = '/'
8
+
9
+ attr_reader :path, :root
10
+
11
+ def initialize(path, root: BLANK)
12
+ @path = path
13
+ @root = root
14
+ end
15
+
16
+ def relative_path
17
+ path.delete_prefix(root).delete_prefix(File::SEPARATOR)
18
+ end
19
+
20
+ def full_mime_type
21
+ @full_mime_type ||= IO.popen(
22
+ ['file', '--brief', '--mime-type', path],
23
+ in: :close, err: :close
24
+ ) { |io| io.read.chomp }.to_s
25
+ end
26
+
27
+ def mime_type
28
+ full_mime_type.split(MIME_TYPE_SEPARATOR).first
29
+ end
30
+
31
+ def mime_subtype
32
+ full_mime_type.split(MIME_TYPE_SEPARATOR).last
33
+ end
34
+
35
+ def digest
36
+ File.directory?(path) ? BLANK : Digest::SHA256.file(path).hexdigest
37
+ end
38
+
39
+ def last_modified_at
40
+ File.mtime(path).utc
41
+ end
42
+
43
+ def bytesize
44
+ File.size(path)
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'file_info'
4
+
5
+ module Kitkat
6
+ # Directory operations.
7
+ class Reader
8
+ attr_reader :root
9
+
10
+ def initialize(root)
11
+ @root = File.expand_path(root)
12
+
13
+ freeze
14
+ end
15
+
16
+ def each(&block)
17
+ return enum_for(:each) unless block_given?
18
+
19
+ traverse(root, &block)
20
+
21
+ self
22
+ end
23
+
24
+ private
25
+
26
+ def traverse(dir, &block)
27
+ Dir[File.join(dir, '*')].each do |path|
28
+ yield FileInfo.new(path, root: root)
29
+
30
+ traverse(path, &block) if File.directory?(path)
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kitkat
4
+ VERSION = '0.0.1'
5
+ end
data/lib/kitkat.rb ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'digest'
4
+ require 'sqlite3'
5
+
6
+ require_relative 'kitkat/database'
7
+ require_relative 'kitkat/reader'
8
+
9
+ # Main example/easiest entry-point for this application.
10
+ module Kitkat
11
+ class << self
12
+ def crawl(path:, db:, io: $stdout)
13
+ reader = Reader.new(path)
14
+ db = Database.new(db)
15
+
16
+ reader.each.with_index(1) do |file_info, index|
17
+ io.puts("[#{index}] #{file_info.relative_path}")
18
+
19
+ db.insert(file_info)
20
+ end
21
+
22
+ io.puts('Complete')
23
+ end
24
+ end
25
+ end
metadata ADDED
@@ -0,0 +1,230 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kitkat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Matthew Ruggio
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2022-06-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: sqlite3
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: bundler-audit
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: guard-rspec
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: pry
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
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop-rake
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: simplecov
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov-console
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ description: " Small library that can populate a SQLite database with the recursive
168
+ list of all files and their respective metadata.\n"
169
+ email:
170
+ - mattruggio@icloud.com
171
+ executables:
172
+ - kitkat
173
+ extensions: []
174
+ extra_rdoc_files: []
175
+ files:
176
+ - ".editorconfig"
177
+ - ".github/workflows/rubygem.yml"
178
+ - ".gitignore"
179
+ - ".rubocop.yml"
180
+ - ".tool-versions"
181
+ - CODE_OF_CONDUCT.md
182
+ - Gemfile
183
+ - Guardfile
184
+ - README.md
185
+ - Rakefile
186
+ - bin/_guard-core
187
+ - bin/bundle-audit
188
+ - bin/bundler-audit
189
+ - bin/console
190
+ - bin/guard
191
+ - bin/rake
192
+ - bin/rspec
193
+ - bin/rubocop
194
+ - exe/kitkat
195
+ - kitkat.gemspec
196
+ - lib/kitkat.rb
197
+ - lib/kitkat/database.rb
198
+ - lib/kitkat/file_info.rb
199
+ - lib/kitkat/reader.rb
200
+ - lib/kitkat/version.rb
201
+ homepage: https://github.com/mattruggio/kitkat
202
+ licenses:
203
+ - MIT
204
+ metadata:
205
+ bug_tracker_uri: https://github.com/mattruggio/kitkat/issues
206
+ changelog_uri: https://github.com/mattruggio/kitkat/blob/main/CHANGELOG.md
207
+ documentation_uri: https://www.rubydoc.info/gems/kitkat
208
+ homepage_uri: https://github.com/mattruggio/kitkat
209
+ source_code_uri: https://github.com/mattruggio/kitkat
210
+ rubygems_mfa_required: 'true'
211
+ post_install_message:
212
+ rdoc_options: []
213
+ require_paths:
214
+ - lib
215
+ required_ruby_version: !ruby/object:Gem::Requirement
216
+ requirements:
217
+ - - ">="
218
+ - !ruby/object:Gem::Version
219
+ version: '2.6'
220
+ required_rubygems_version: !ruby/object:Gem::Requirement
221
+ requirements:
222
+ - - ">="
223
+ - !ruby/object:Gem::Version
224
+ version: '0'
225
+ requirements: []
226
+ rubygems_version: 3.0.3
227
+ signing_key:
228
+ specification_version: 4
229
+ summary: File/Metadata Database Populator
230
+ test_files: []