qq 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. checksums.yaml +7 -0
  2. data/bin/qq +30 -0
  3. data/lib/qq.rb +86 -0
  4. metadata +74 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 862a2cd90b5250cf9b88e39dbf7393ed16118dca
4
+ data.tar.gz: 234ba9609d7c38c6019755308a6048299c18d3df
5
+ SHA512:
6
+ metadata.gz: 0971bd8de1779756b33608026cad14a7e162e68cb5a419abcdb21df58433ef20a48aea964e399c32f1573919ed58e1065033de04b0926cfdf554f073f47c5528
7
+ data.tar.gz: 6e331cfa370512cdc875d05e3d642c3020458a99ae30aa01b9235ad68aebe1f8218185025abe9ea09b44672baf7f7a2b6f88fd9edcf6894b43e976cad9798e9e
data/bin/qq ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ require 'optparse'
4
+ require 'tmpdir'
5
+
6
+ QFILE = File.join(Dir.tmpdir, 'q')
7
+
8
+ options = {}
9
+ OptionParser.new do |opts|
10
+ opts.banner = "usage: qq [options]"
11
+
12
+ opts.on('--tmpdir', 'Print system tempdir to stdout.') do
13
+ puts Dir.tmpdir
14
+ exit
15
+ end
16
+
17
+ opts.on('--truncate', 'Truncate qq temp file.') do
18
+ File.truncate(QFILE, 0)
19
+ exit
20
+ end
21
+
22
+ opts.on('-h', '--help') do
23
+ puts opts
24
+ exit
25
+ end
26
+ end.parse!
27
+
28
+ FileUtils.touch(QFILE) unless File.exists?(QFILE)
29
+ exec 'tail', '-f', QFILE
30
+
@@ -0,0 +1,86 @@
1
+ require 'pp'
2
+ require 'tmpdir'
3
+ require 'thread'
4
+ require 'parser'
5
+ require 'unparser'
6
+
7
+ # QQ improves puts debugging.
8
+ #
9
+ # All output goes to 'q' in your `Dir.tempdir`, normally '/tmp/q'.
10
+ #
11
+ # touch /tmp/q && tail -f /tmp/q
12
+ #
13
+ # To print the value of something require 'qq' and use qq() anywhere you would
14
+ # have previously used pp(), puts etc and searched log files, $stderr, $stdout
15
+ # etc. for your debugging.
16
+ #
17
+ # @example
18
+ # require 'qq'; qq('hello world')
19
+ # @see Python https://github.com/zestyping/q
20
+ # @see Go https://github.com/y0ssar1an/q
21
+ #--
22
+ # TODO: Calling Q twice on the same line will cause issues because
23
+ # Thread::Backtrace::Location doesn't give us a character only a line.
24
+ class QQ < Parser::AST::Processor
25
+ NORMAL, YELLOW, CYAN = "\x1b[0m", "\x1b[33m", "\x1b[36m"
26
+
27
+ @@mutex ||= Mutex.new
28
+ @@start ||= Time.now
29
+ @@location ||= nil
30
+
31
+ # @see Kernel#qq
32
+ #--
33
+ # TODO: Complain if called directly.
34
+ def initialize location, args
35
+ @location, @args = location, args
36
+ @@mutex.synchronize do
37
+ begin
38
+ # Parse the statement that generated the argument from source.
39
+ process(Parser::CurrentRuby.parse(File.read(location.absolute_path)))
40
+ rescue StandardError
41
+ # Failed to parse or embedded Ruby (HAML, ERB, ...) prints the position of each argument in qq()
42
+ # location preamble/header.
43
+ # line:0 arg:0 = ...
44
+ # line:0 arg:1 = ...
45
+ write args.each_with_index.map{|arg, position| [arg, 'line:%d arg:%d' % [@location.lineno, position]]}
46
+ end
47
+ end
48
+ end
49
+
50
+ def on_send ast_node
51
+ return unless ast_node.loc.line == @location.lineno
52
+ ast_receiver, ast_method, *ast_args = *ast_node
53
+
54
+ return if ast_receiver || ast_method != :qq
55
+ write @args.zip(ast_args).map{|arg, ast_arg| [arg, ast_arg.loc.expression.source]}
56
+ end
57
+
58
+ protected
59
+ def write args
60
+ File.open(File.join(Dir.tmpdir, 'q'), 'a') do |fh|
61
+ now = Time.now
62
+
63
+ if @@start <= now - 2 || @@location&.label != @location.label
64
+ fh.write "\n%s[%s] %s\n" % [NORMAL, now.strftime('%T'), @location]
65
+ @@start = now
66
+ end
67
+
68
+ args.each do |arg, arg_source|
69
+ fh.write [YELLOW, "%1.3fs " % (now - @@start), NORMAL, arg_source, ' = ', CYAN].join
70
+ PP.pp(arg, fh)
71
+ fh.write NORMAL
72
+ end
73
+
74
+ @@location = @location
75
+ end
76
+ end
77
+ end
78
+
79
+ module Kernel
80
+ # Pretty print statements with QQ.
81
+ #
82
+ # @example qq('hello world')
83
+ def qq *args
84
+ QQ.new(caller_locations(1, 1).first, args)
85
+ end
86
+ end
metadata ADDED
@@ -0,0 +1,74 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: qq
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Shane Hanna
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parser
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: unparser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.2'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.2'
41
+ description: Improved puts debugging output for busy Ruby programmers.
42
+ email: shane.hanna@gmail.com
43
+ executables:
44
+ - qq
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - bin/qq
49
+ - lib/qq.rb
50
+ homepage: https://github.com/techspaceco/qq
51
+ licenses:
52
+ - MIT
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options: []
56
+ require_paths:
57
+ - lib
58
+ required_ruby_version: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ required_rubygems_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ requirements: []
69
+ rubyforge_project:
70
+ rubygems_version: 2.5.1
71
+ signing_key:
72
+ specification_version: 4
73
+ summary: Improved pp debugging.
74
+ test_files: []