tagrity 0.1.3 → 0.1.4
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 +4 -4
- data/Gemfile.lock +1 -1
- data/README.md +41 -0
- data/foobar.rb +0 -0
- data/lib/tagrity/cli.rb +16 -9
- data/lib/tagrity/commands/start.rb +4 -3
- data/lib/tagrity/config_file.rb +17 -3
- data/lib/tagrity/file_callbacks.rb +4 -0
- data/lib/tagrity/helper.rb +57 -0
- data/lib/tagrity/pid_file.rb +9 -20
- data/lib/tagrity/tag_generator.rb +54 -11
- data/lib/tagrity/version.rb +1 -1
- metadata +4 -4
- data/lib/tagrity/executable_helper.rb +0 -9
- data/lib/tagrity/process_helper.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0ee6568e2b6eece64b41ea5bfd180aff6770f909d2ae0a2d1b113d6776913bf7
|
4
|
+
data.tar.gz: 963d36ade8dcae0fcf5f9457c057c2ca99984c0e6c27ca5d583bfee960b0fd0e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07b68faab753df68dd50a90c0059498b35f55de439fd228e04a93d246489b3db50073d148c644bce12007d2c119bd6deaa9c3a17156d2680fa36f3f87aeea26e
|
7
|
+
data.tar.gz: 73d254a884b320d83fa06c794a7e30940b29d7021915ae8c4374f5d34c675a9af2a2d25c55bf42f37704e93dbba49263d0e0bcc2ca14c82e46bc6709204a836c
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -84,3 +84,44 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
84
84
|
## Code of Conduct
|
85
85
|
|
86
86
|
Everyone interacting in the Tagrity project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/tagrity/blob/master/CODE_OF_CONDUCT.md).
|
87
|
+
|
88
|
+
|
89
|
+
|
90
|
+
|
91
|
+
tagrity config to use (default to ~/.config/tagrity/config.yml if available).
|
92
|
+
A config file is a yaml file with the following possible values.
|
93
|
+
Some of these can be overridden with options, however the configfile
|
94
|
+
provided via --configfile will override the global config file in
|
95
|
+
~/.config/tagrity/config.yml
|
96
|
+
```
|
97
|
+
# ext_cmds allows different tag generators to be used depending on the file extension.
|
98
|
+
# Multiple extensions does not work, *.html.erb files will be picked up as erb.
|
99
|
+
# ext_cmds:
|
100
|
+
# <file extension>: <command to use to generate tags for this file extension>
|
101
|
+
# DEFAULT: empty
|
102
|
+
ext_cmds:
|
103
|
+
rb: ripper-tags
|
104
|
+
c: ctags
|
105
|
+
go: gotags
|
106
|
+
|
107
|
+
# default_cmd specifies the default command to be used to generate tags
|
108
|
+
# default_cmd: <command>
|
109
|
+
# DEFAULT: ctags
|
110
|
+
default_cmd: ctags
|
111
|
+
|
112
|
+
# tagf is the filename (relative) to generate tags into
|
113
|
+
# tagf: <filename>
|
114
|
+
# DEFAULT: tags
|
115
|
+
tagf: tags
|
116
|
+
|
117
|
+
# excluded_exts specifies which file extensions to not generate tags for.
|
118
|
+
# excluded_exts: [<file extension>, ...]
|
119
|
+
# DEFAULT: []
|
120
|
+
excluded_exts: [rb, h, js]
|
121
|
+
|
122
|
+
# excluded_paths specifies which paths to ignore.
|
123
|
+
# It's usually better to avoid this since by default tagrity will only look
|
124
|
+
# at files which are tracked by git.
|
125
|
+
# excluded_paths: [<path>, ...]
|
126
|
+
# DEFAULT: []
|
127
|
+
excluded_paths: [vendor, node_modules]
|
data/foobar.rb
ADDED
File without changes
|
data/lib/tagrity/cli.rb
CHANGED
@@ -6,16 +6,18 @@ require 'tagrity/commands/status'
|
|
6
6
|
module Tagrity
|
7
7
|
class CLI < Thor
|
8
8
|
desc "start", "Start watching a directory (default to pwd)"
|
9
|
-
option :dir
|
10
|
-
option :
|
11
|
-
option :
|
12
|
-
option :
|
13
|
-
option :
|
14
|
-
option :
|
15
|
-
option :
|
9
|
+
option :dir, desc: "directory to watch (omit to use pwd)"
|
10
|
+
option :fresh, type: :boolean, default: false, desc: "index the whole codebase before watching the file system."
|
11
|
+
option :tagf, desc: "filename (relative) to generate tags into (default: 'tags')."
|
12
|
+
option :git, type: :boolean, default: true, desc: "only index files which are being tracked by git"
|
13
|
+
option :fg, type: :boolean, desc: "keep the tagrity process running in the foreground"
|
14
|
+
option :configfile, desc: "See README for more info."
|
15
|
+
option :default_cmd, desc: "the default command to be used to generate tags (default: 'ctags')"
|
16
|
+
option :excluded_exts, type: :array, desc: "which file extensions to not generate tags for."
|
17
|
+
option :excluded_paths, type: :array, desc: "which paths to ignore. Usually better to ignore this since by default only file tracked by git are indexed."
|
16
18
|
def start()
|
17
19
|
setup_config
|
18
|
-
Command::Start::call(dir, fg?)
|
20
|
+
Command::Start::call(dir, fg?, fresh?)
|
19
21
|
end
|
20
22
|
|
21
23
|
desc "stop", "Stop watching a directory (default to pwd)"
|
@@ -41,13 +43,18 @@ module Tagrity
|
|
41
43
|
options[:fg]
|
42
44
|
end
|
43
45
|
|
46
|
+
def fresh?
|
47
|
+
options[:fresh]
|
48
|
+
end
|
49
|
+
|
44
50
|
def setup_config
|
45
51
|
ConfigFile.instance.init(
|
46
52
|
configfile: options[:configfile],
|
47
53
|
default_cmd: options[:default_cmd],
|
48
54
|
tagf: options[:tagf],
|
49
55
|
excluded_exts: options[:excluded_exts],
|
50
|
-
excluded_paths: options[:excluded_paths]
|
56
|
+
excluded_paths: options[:excluded_paths],
|
57
|
+
git: options[:git]
|
51
58
|
)
|
52
59
|
end
|
53
60
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'listen'
|
2
2
|
require 'tagrity/pid_file'
|
3
|
-
require 'tagrity/
|
3
|
+
require 'tagrity/helper'
|
4
4
|
require 'tagrity/file_callbacks'
|
5
5
|
require 'tagrity/provider'
|
6
6
|
|
@@ -10,7 +10,7 @@ module Tagrity
|
|
10
10
|
class ErrorProcessAlreadyRunning < StandardError; end
|
11
11
|
|
12
12
|
class << self
|
13
|
-
def call(dir, fg)
|
13
|
+
def call(dir, fg, fresh)
|
14
14
|
assert_not_running(dir)
|
15
15
|
|
16
16
|
Process.daemon(nochdir: true) unless fg
|
@@ -18,9 +18,10 @@ module Tagrity
|
|
18
18
|
callbacks = Provider.provide(:file_callbacks)
|
19
19
|
PidFile.write(PidFile.new(dir, Process.pid))
|
20
20
|
|
21
|
+
callbacks.on_fresh if fresh
|
22
|
+
|
21
23
|
listener = Listen.to(
|
22
24
|
dir,
|
23
|
-
ignore: [/^\.?tags$/],
|
24
25
|
relative: true,
|
25
26
|
) do |modified, added, removed|
|
26
27
|
callbacks.on_files_modified(modified)
|
data/lib/tagrity/config_file.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'singleton'
|
3
|
-
require 'tagrity/
|
3
|
+
require 'tagrity/helper'
|
4
4
|
|
5
5
|
module Tagrity
|
6
6
|
class ConfigFile
|
7
7
|
include Singleton
|
8
8
|
|
9
9
|
class ErrorTagFileNotWritable < StandardError; end
|
10
|
+
class ErrorGitNotExecutable < StandardError; end
|
10
11
|
|
11
12
|
def init(
|
12
13
|
configfile:,
|
13
14
|
default_cmd:,
|
14
15
|
tagf:,
|
15
16
|
excluded_exts:,
|
16
|
-
excluded_paths
|
17
|
+
excluded_paths:,
|
18
|
+
git:
|
17
19
|
)
|
18
20
|
fname = config_file_name(configfile)
|
19
21
|
@config = if fname.nil? then {} else YAML.load_file(fname) end
|
@@ -22,11 +24,12 @@ module Tagrity
|
|
22
24
|
ensure_tagf(tagf)
|
23
25
|
ensure_excluded_exts(excluded_exts)
|
24
26
|
ensure_excluded_paths(excluded_paths)
|
27
|
+
ensure_git(git)
|
25
28
|
end
|
26
29
|
|
27
30
|
def ft_to_cmd(ext)
|
28
31
|
ft_cmd = @config['ext_cmds'][ext]
|
29
|
-
return @config['default_cmd'] if ft_cmd.nil? || !
|
32
|
+
return @config['default_cmd'] if ft_cmd.nil? || !Helper.is_executable?(ft_cmd)
|
30
33
|
ft_cmd
|
31
34
|
end
|
32
35
|
|
@@ -42,6 +45,10 @@ module Tagrity
|
|
42
45
|
@config['tagf']
|
43
46
|
end
|
44
47
|
|
48
|
+
def respect_git?
|
49
|
+
@config['git']
|
50
|
+
end
|
51
|
+
|
45
52
|
def to_s
|
46
53
|
@config.to_s
|
47
54
|
end
|
@@ -71,6 +78,13 @@ module Tagrity
|
|
71
78
|
end
|
72
79
|
end
|
73
80
|
|
81
|
+
def ensure_git(git)
|
82
|
+
set_option('git', git, true)
|
83
|
+
if @config['git'] && !Helper.is_executable?('git')
|
84
|
+
raise ErrorGitNotExecutable, "'git' must be executable to use the --git option."
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
74
88
|
def set_option(key, local_val, default)
|
75
89
|
unless local_val.nil?
|
76
90
|
@config[key] = local_val
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Tagrity
|
2
|
+
class Helper
|
3
|
+
root = ENV['TEST'] ? __dir__ : "#{ENV['HOME']}/.tagrity/"
|
4
|
+
RUN_DIR = File.join(root, 'var/run').freeze
|
5
|
+
LOG_DIR = File.join(root, 'var/log').freeze
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def run_dir
|
9
|
+
ensure_data_dirs
|
10
|
+
RUN_DIR
|
11
|
+
end
|
12
|
+
|
13
|
+
def is_executable?(cmd)
|
14
|
+
!%x{command -v #{cmd}}.empty?
|
15
|
+
end
|
16
|
+
|
17
|
+
def kill(pid)
|
18
|
+
Process.kill('HUP', pid)
|
19
|
+
end
|
20
|
+
|
21
|
+
def alive?(pid)
|
22
|
+
Process.kill(0, pid) # signal 0 checks if pid is alive
|
23
|
+
true
|
24
|
+
rescue Errno::ESRCH
|
25
|
+
false
|
26
|
+
rescue Errno::EPERM
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
def is_git_dir?
|
31
|
+
return @is_git_dir unless @is_git_dir.nil?
|
32
|
+
`git rev-parse --git-dir &> /dev/null`
|
33
|
+
if $?.exitstatus == 0
|
34
|
+
@is_git_dir = true
|
35
|
+
else
|
36
|
+
@is_git_dir = false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def is_file_ignored?(file)
|
41
|
+
`git check-ignore -q #{file} &> /dev/null`
|
42
|
+
$?.exitstatus == 0
|
43
|
+
end
|
44
|
+
|
45
|
+
def is_file_tracked?(file)
|
46
|
+
`git ls-files --error-unmatch #{file} &> /dev/null`
|
47
|
+
$?.exitstatus == 0
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def ensure_data_dirs
|
53
|
+
FileUtils.mkdir_p(RUN_DIR)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/tagrity/pid_file.rb
CHANGED
@@ -1,31 +1,31 @@
|
|
1
|
+
require 'tagrity/helper'
|
2
|
+
|
1
3
|
module Tagrity
|
2
4
|
class PidFile
|
3
|
-
RUN_DIR = "#{ENV['HOME']}/.tagrity/var/run"
|
4
|
-
|
5
5
|
class << self
|
6
6
|
def write(pid_file)
|
7
|
-
File.write("#{run_dir}/#{pid_file.name}", pid_file.dir)
|
7
|
+
File.write("#{Helper.run_dir}/#{pid_file.name}", pid_file.dir)
|
8
8
|
end
|
9
9
|
|
10
10
|
def delete(dir)
|
11
|
-
pid_file_paths = Dir.glob("#{run_dir}/#{dir.split('/').last}.*.pid").select do |path|
|
11
|
+
pid_file_paths = Dir.glob("#{Helper.run_dir}/#{dir.split('/').last}.*.pid").select do |path|
|
12
12
|
full_dir = File.read(path)
|
13
13
|
File.realdirpath(full_dir) == File.realdirpath(dir)
|
14
14
|
end
|
15
15
|
|
16
16
|
pid_file_paths.each do |path|
|
17
17
|
File.delete(path)
|
18
|
-
|
18
|
+
Helper.kill(pid_from_path(path))
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
22
|
def alive_pid_files(dir: nil)
|
23
|
-
Dir.glob("#{run_dir}/*").reduce([]) do |pid_files, path|
|
23
|
+
Dir.glob("#{Helper.run_dir}/*").reduce([]) do |pid_files, path|
|
24
24
|
pid = pid_from_path(path)
|
25
25
|
pid_file_dir = File.read(path)
|
26
26
|
|
27
27
|
if dir.nil? || is_same_dirs(pid_file_dir, dir)
|
28
|
-
if
|
28
|
+
if Helper.alive?(pid)
|
29
29
|
pid_files << PidFile.new(pid_file_dir, pid)
|
30
30
|
else
|
31
31
|
File.delete(path)
|
@@ -36,23 +36,12 @@ module Tagrity
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
-
def run_dir
|
40
|
-
ensure_dirs
|
41
|
-
RUN_DIR
|
42
|
-
end
|
43
|
-
|
44
39
|
private
|
45
40
|
|
46
41
|
def is_same_dirs(dir1, dir2)
|
47
42
|
File.realdirpath(dir1) == File.realdirpath(dir2)
|
48
43
|
end
|
49
44
|
|
50
|
-
def ensure_dirs
|
51
|
-
return if @ensure_dirs_done
|
52
|
-
FileUtils.mkdir_p(RUN_DIR)
|
53
|
-
@ensure_dirs_done = true
|
54
|
-
end
|
55
|
-
|
56
45
|
def pid_from_path(pid_file_name)
|
57
46
|
pid_file_name.split('.')[-2].to_i
|
58
47
|
end
|
@@ -76,13 +65,13 @@ module Tagrity
|
|
76
65
|
|
77
66
|
def delete
|
78
67
|
File.delete(pid_file_path)
|
79
|
-
|
68
|
+
Helper.kill(pid.to_i)
|
80
69
|
end
|
81
70
|
|
82
71
|
private
|
83
72
|
|
84
73
|
def pid_file_path
|
85
|
-
"#{
|
74
|
+
"#{Helper.run_dir}/#{name}"
|
86
75
|
end
|
87
76
|
end
|
88
77
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require '
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'tagrity/helper'
|
2
3
|
|
3
4
|
module Tagrity
|
4
5
|
class TagGenerator
|
@@ -9,37 +10,73 @@ module Tagrity
|
|
9
10
|
@config = ConfigFile.instance
|
10
11
|
end
|
11
12
|
|
13
|
+
def generate_all
|
14
|
+
if File.exists?(tagf)
|
15
|
+
File.delete(tagf)
|
16
|
+
end
|
17
|
+
if check_git?
|
18
|
+
files = `git ls-files 2> /dev/null`.split
|
19
|
+
else
|
20
|
+
files = `find * 2> /dev/null`.split
|
21
|
+
end
|
22
|
+
if $?.exitstatus == 0
|
23
|
+
generate(files)
|
24
|
+
else
|
25
|
+
puts "Failed to get a listing of all files under pwd for use with --fresh."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
12
29
|
def generate(files)
|
13
30
|
return if files.empty?
|
14
31
|
files
|
15
|
-
.select { |file|
|
32
|
+
.select { |file| generate_tags?(file) }
|
16
33
|
.group_by { |file| @config.ft_to_cmd(file.partition('.').last) }
|
17
34
|
.each do |cmd, fnames|
|
18
|
-
`#{cmd} -f #{tagf} --append #{fnames.join(' ')}`
|
19
|
-
if $?.exitstatus
|
20
|
-
puts "{#{cmd}} failed to generate tags for #{fnames} into #{tagf}"
|
21
|
-
else
|
35
|
+
`#{cmd} -f #{tagf} --append #{fnames.join(' ')} &> /dev/null`
|
36
|
+
if $?.exitstatus == 0
|
22
37
|
puts "{#{cmd}} generated tags for #{fnames} into #{tagf}"
|
38
|
+
else
|
39
|
+
puts "{#{cmd}} failed to generate tags for #{fnames} into #{tagf}"
|
23
40
|
end
|
24
41
|
end
|
25
42
|
end
|
26
43
|
|
27
44
|
def delete_files_tags(files)
|
28
45
|
return if files.empty?
|
29
|
-
`cat #{tagf} | grep -v -F #{files.map { |f| " -e \" #{f} \""}.join(' ')} >
|
30
|
-
|
31
|
-
|
46
|
+
`cat #{tagf} | grep -v -F #{files.map { |f| " -e \" #{f} \""}.join(' ')} > #{tmp_file} 2> /dev/null`
|
47
|
+
if $?.exitstatus == 0
|
48
|
+
`mv -f #{tmp_file} #{tagf}`
|
49
|
+
puts "Deleted tags for #{files} from #{tagf}"
|
50
|
+
else
|
51
|
+
puts "Failed to delete tags for #{files} from #{tagf}"
|
52
|
+
end
|
32
53
|
end
|
33
54
|
|
34
55
|
private
|
35
56
|
|
36
|
-
def
|
57
|
+
def generate_tags?(file)
|
58
|
+
copacetic_with_git?(file) && indexable?(file)
|
59
|
+
end
|
60
|
+
|
61
|
+
def indexable?(file)
|
62
|
+
file != tagf && !is_file_excluded(file) && File.readable?(file)
|
63
|
+
end
|
64
|
+
|
65
|
+
def copacetic_with_git?(file)
|
66
|
+
!(check_git? && !Helper.is_file_tracked?(file))
|
67
|
+
end
|
68
|
+
|
69
|
+
def check_git?
|
70
|
+
@config.respect_git? && Helper.is_git_dir?
|
71
|
+
end
|
72
|
+
|
73
|
+
def is_file_excluded(fname)
|
37
74
|
@config.is_ft_excluded(fname.partition('.').last) || @config.is_path_excluded(fname)
|
38
75
|
end
|
39
76
|
|
40
77
|
def assert_executables
|
41
78
|
%w(cat grep mv).each do |exe|
|
42
|
-
if !
|
79
|
+
if !Helper.is_executable?(exe)
|
43
80
|
raise ExecutableNonExist, "tagrity depends on the executable #{exe}"
|
44
81
|
end
|
45
82
|
end
|
@@ -48,5 +85,11 @@ module Tagrity
|
|
48
85
|
def tagf
|
49
86
|
@config.tagf
|
50
87
|
end
|
88
|
+
|
89
|
+
def tmp_file
|
90
|
+
tmpdir = "#{Dir.tmpdir}/tagrity"
|
91
|
+
FileUtils.mkdir_p(tmpdir)
|
92
|
+
"#{tmpdir}/#{Process.pid}.tmptags"
|
93
|
+
end
|
51
94
|
end
|
52
95
|
end
|
data/lib/tagrity/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tagrity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam P. Regasz-Rethy
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -114,16 +114,16 @@ files:
|
|
114
114
|
- bin/console
|
115
115
|
- bin/setup
|
116
116
|
- exe/tagrity
|
117
|
+
- foobar.rb
|
117
118
|
- lib/tagrity.rb
|
118
119
|
- lib/tagrity/cli.rb
|
119
120
|
- lib/tagrity/commands/start.rb
|
120
121
|
- lib/tagrity/commands/status.rb
|
121
122
|
- lib/tagrity/commands/stop.rb
|
122
123
|
- lib/tagrity/config_file.rb
|
123
|
-
- lib/tagrity/executable_helper.rb
|
124
124
|
- lib/tagrity/file_callbacks.rb
|
125
|
+
- lib/tagrity/helper.rb
|
125
126
|
- lib/tagrity/pid_file.rb
|
126
|
-
- lib/tagrity/process_helper.rb
|
127
127
|
- lib/tagrity/provider.rb
|
128
128
|
- lib/tagrity/tag_generator.rb
|
129
129
|
- lib/tagrity/version.rb
|
@@ -1,18 +0,0 @@
|
|
1
|
-
module Tagrity
|
2
|
-
class ProcessHelper
|
3
|
-
class << self
|
4
|
-
def kill(pid)
|
5
|
-
Process.kill('HUP', pid)
|
6
|
-
end
|
7
|
-
|
8
|
-
def alive?(pid)
|
9
|
-
Process.kill(0, pid) # signal 0 checks if pid is alive
|
10
|
-
true
|
11
|
-
rescue Errno::ESRCH
|
12
|
-
false
|
13
|
-
rescue Errno::EPERM
|
14
|
-
true
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|