batcave 0.0.9 → 0.0.11

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a25e16c495db47fa2c3282ecca632718045bc953
4
+ data.tar.gz: b37c25923e024cb02ce42f67cc91f249da7e844b
5
+ SHA512:
6
+ metadata.gz: c39256bb430dd27a3bab682a63a0721ff855ed210336b06b54528d38086b2fc151b384d15c589d66cb85a3c84e70bc14a7223520f18f4cc846b8dcc09f46e483
7
+ data.tar.gz: 9ce8d3bce04ca99686e88adf9840216a80c391d0ac44d17456d7fafc9e2c3cbb012ca754bdb56f720634eebec016b53e05893d95e71ebb8737b55d17d1019351
data/Gemfile CHANGED
@@ -1,4 +1,2 @@
1
- source :rubygems
2
-
3
- gem "clamp"
4
- gem "cabin"
1
+ source "https://rubygems.org"
2
+ gemspec
@@ -1,10 +1,20 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ batcave (0.0.10)
5
+ cabin
6
+ clamp
7
+ stud (>= 0.0.14)
8
+
1
9
  GEM
2
- remote: http://rubygems.org/
10
+ remote: https://rubygems.org/
3
11
  specs:
4
- clamp (0.3.0)
12
+ cabin (0.6.1)
13
+ clamp (0.6.3)
14
+ stud (0.0.18)
5
15
 
6
16
  PLATFORMS
7
17
  ruby
8
18
 
9
19
  DEPENDENCIES
10
- clamp
20
+ batcave!
@@ -2,7 +2,7 @@ Gem::Specification.new do |spec|
2
2
  files = %x{git ls-files}.split("\n")
3
3
 
4
4
  spec.name = "batcave"
5
- spec.version = "0.0.9"
5
+ spec.version = "0.0.11"
6
6
  spec.summary = "Experiments in tools, boilerplatery, debugging, etc."
7
7
  spec.description = spec.summary
8
8
  spec.add_dependency("clamp")
@@ -11,6 +11,8 @@ Gem::Specification.new do |spec|
11
11
  spec.bindir = "bin"
12
12
  spec.executables << "dk"
13
13
 
14
+ spec.add_dependency("stud", ">= 0.0.14")
15
+ spec.add_dependency("octokit")
14
16
  spec.author = "Jordan Sissel"
15
17
  spec.email = "jls@semicomplete.com"
16
18
  spec.homepage = "https://github.com/jordansissel/batcave"
data/bin/dk CHANGED
@@ -5,4 +5,4 @@ require "clamp"
5
5
 
6
6
  $: << File.join(File.dirname(__FILE__), "..", "lib")
7
7
  require "batcave/main"
8
- exit(BatCave::Main.run)
8
+ exit(BatCave::Main.run || 0)
@@ -0,0 +1,97 @@
1
+ require "clamp"
2
+ require "faraday"
3
+ require "json"
4
+ require "insist"
5
+ require "clamp"
6
+
7
+ class BatCave::Command::GithubIssueMilestone < Clamp::Command
8
+ option ["--log-level", "-l"], "LEVEL", "The log level. Default is 'warn'. Can be 'debug', 'info', 'warn', 'error'", :default => "warn" do |val|
9
+ insist { ["warn", "debug", "info", "error"] }.include?(val.downcase)
10
+ val.downcase.to_sym
11
+ end
12
+ option "--override", :flag, "Override milestone on an issue if one is already set.", :default => false
13
+
14
+ parameter "USER/PROJECT", "The user/project repo name on github.", :attribute_name => "repo"
15
+ parameter "ISSUE", "The issue number. Can be '-' to read issue numbers from stdin.", :attribute_name => :issue_number
16
+ parameter "MILESTONE", "The milestone to set", :attribute_name => :milestone_name
17
+
18
+ def logger
19
+ @logger ||= Cabin::Channel.get
20
+ end
21
+
22
+ def execute
23
+ logger.subscribe(STDOUT)
24
+ logger.level = log_level
25
+ logger[:repo] = repo
26
+ logger[:milestone] = milestone_name
27
+
28
+ # verify milestone exists
29
+ milestones = client.milestones(repo)
30
+ selector = proc { |m| m["title"] == milestone_name }
31
+ if milestones.none?(&selector)
32
+ raise "No such milestone '#{milestone_name}' found in #{repo}"
33
+ end
34
+ milestone_number = milestones.find(&selector)["number"]
35
+
36
+ logger.debug("Found milestone number", :number => milestone_number)
37
+
38
+ if issue_number == "-"
39
+ STDIN.each_line do |issue_number|
40
+ set_milestone(repo, issue_number.chomp, milestone_number)
41
+ end
42
+ else
43
+ set_milestone(repo, issue_number, milestone_number)
44
+ end
45
+ 0
46
+ rescue RuntimeError => e
47
+ puts "Error: #{e}"
48
+ 1
49
+ rescue => e
50
+ if logger.debug?
51
+ logger.error("An error occurred", :exception => e, :backtrace => e.backtrace)
52
+ else
53
+ logger.error("An error occurred", :exception => e)
54
+ end
55
+ 1
56
+ end # def execute
57
+
58
+ def set_milestone(repo, issue_number, milestone_number)
59
+ logger[:issue] = issue_number
60
+
61
+ # TODO(sissel): Verify issue exists
62
+ issue = client.issue(repo, issue_number)
63
+ if issue.milestone
64
+ if issue.milestone.title == milestone_name
65
+ logger.debug("Skipping because milestone is already set", :current_milestone => issue.milestone.title)
66
+ return
67
+ end
68
+ if issue.milestone.title != milestone_name
69
+ if override?
70
+ logger.info("Milestone already set on issue, but override is given, so I will override it.", :current_milestone => issue.milestone.title)
71
+ else
72
+ logger.info("Milestone already set on issue, skipping this issue.", :current_milestone => issue.milestone.title)
73
+ #raise "Milestone is already set on '#{repo}' issue #{issue_number}"
74
+ end
75
+ end
76
+ end
77
+ client.update_issue(repo, issue_number, issue.title, issue.body, :milestone => milestone_number)
78
+ logger.info("Updated issue milestone successfully", :repo => repo)
79
+ end # def execute
80
+
81
+ def client
82
+ # This requires you have ~/.netrc setup correctly
83
+ # I don't know if it works with 2FA
84
+ require "octokit"
85
+ @client ||= Octokit::Client.new(:netrc => true).tap do |client|
86
+ client.login
87
+ client.auto_paginate = true
88
+ end
89
+ end
90
+
91
+ def http
92
+ @http ||= Faraday.new(:url => "https://github.com") do |faraday|
93
+ faraday.request :url_encoded
94
+ faraday.adapter Faraday.default_adapter
95
+ end # http
96
+ end # def http
97
+ end # class BatCave::Command::GithubIssueMilestone
@@ -0,0 +1,63 @@
1
+ require "clamp"
2
+ require "batcave/namespace"
3
+ require "stud/temporary"
4
+
5
+ class BatCave::Command::SmartEdit < Clamp::Command
6
+ def execute
7
+ rspec_failure = /^ *Failure\/Error/
8
+ rspec_stack_trace = /^ *# (?<path>[^:]+):(?<line>[0-9]+):/
9
+ text = capture_tmux
10
+ if text =~ rspec_failure
11
+ lines = text.split("\n")
12
+ # first failure/error
13
+ index = lines.find_index { |l| l =~ rspec_failure }
14
+ # then find all lines that look like stack traces.
15
+ traces = []
16
+ last_line = index
17
+ lines[index..-1].each_with_index do |line, i|
18
+ m = rspec_stack_trace.match(line)
19
+ if m
20
+ traces << Hash[m.names.zip(m.captures)]
21
+ elsif traces.count > 0 && line =~ /^ *$/
22
+ # already found traces, and a blank line means the end of the trace.
23
+ last_line = i
24
+ break
25
+ end
26
+ end
27
+
28
+ if traces.any?
29
+ # Find the most-recently modified file.
30
+ candidate = traces.sort_by { |t| File.stat(t["path"]).mtime }.reverse.first
31
+ Stud::Temporary.file do |fd|
32
+ lines[index .. last_line + index].each do |line|
33
+ fd.puts(line)
34
+ end
35
+ fd.flush
36
+
37
+ system("tmux split-window -l 7 'cat #{fd.path}; sleep 3000 ' \\; last-pane")
38
+ system("#{ENV["EDITOR"]} #{candidate["path"]} +#{candidate["line"]}")
39
+ system("tmux last-pane \\; kill-pane")
40
+ end
41
+ end
42
+ end
43
+
44
+ return 0
45
+ end
46
+
47
+ def tmux?
48
+ return ENV["TMUX"]
49
+ end
50
+
51
+ def screen?
52
+ return ENV["STY"]
53
+ end
54
+
55
+ def capture_tmux
56
+ Stud::Temporary.file do |fd|
57
+ # Capture the current screen plus 50 lines of history
58
+ system("tmux capture-pane -S -50")
59
+ system("tmux save-buffer -b 0 #{fd.path}")
60
+ return fd.read
61
+ end
62
+ end
63
+ end
@@ -3,6 +3,8 @@ require "batcave/namespace"
3
3
  require "batcave/command/add"
4
4
  require "batcave/command/update"
5
5
  require "batcave/command/test"
6
+ require "batcave/command/smart-edit"
7
+ require "batcave/command/github-issue-milestone"
6
8
  require "cabin"
7
9
 
8
10
  class BatCave::Main < Clamp::Command
@@ -22,4 +24,9 @@ class BatCave::Main < Clamp::Command
22
24
 
23
25
  # Run a file's tests.
24
26
  subcommand "test", "Run the tests for a given file", BatCave::Command::Test
27
+
28
+ # Figure out what file to edit and do it.
29
+ subcommand "smart-edit", "Scan the screen for a file to edit", BatCave::Command::SmartEdit
30
+
31
+ subcommand "github-issue-milestone", "Set a milestone on an issue", BatCave::Command::GithubIssueMilestone
25
32
  end
metadata CHANGED
@@ -1,46 +1,69 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: batcave
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
5
- prerelease:
4
+ version: 0.0.11
6
5
  platform: ruby
7
6
  authors:
8
7
  - Jordan Sissel
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-10-18 00:00:00.000000000 Z
11
+ date: 2014-11-11 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: clamp
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ! '>='
24
+ - - ">="
28
25
  - !ruby/object:Gem::Version
29
26
  version: '0'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: cabin
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ! '>='
31
+ - - ">="
36
32
  - !ruby/object:Gem::Version
37
33
  version: '0'
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ! '>='
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: stud
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.14
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.0.14
55
+ - !ruby/object:Gem::Dependency
56
+ name: octokit
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
44
67
  - !ruby/object:Gem::Version
45
68
  version: '0'
46
69
  description: Experiments in tools, boilerplatery, debugging, etc.
@@ -50,7 +73,7 @@ executables:
50
73
  extensions: []
51
74
  extra_rdoc_files: []
52
75
  files:
53
- - .gitignore
76
+ - ".gitignore"
54
77
  - Gemfile
55
78
  - Gemfile.lock
56
79
  - Makefile
@@ -59,6 +82,8 @@ files:
59
82
  - bin/dk
60
83
  - lib/batcave/action/add.rb
61
84
  - lib/batcave/command/add.rb
85
+ - lib/batcave/command/github-issue-milestone.rb
86
+ - lib/batcave/command/smart-edit.rb
62
87
  - lib/batcave/command/test.rb
63
88
  - lib/batcave/command/update.rb
64
89
  - lib/batcave/dsl.rb
@@ -81,27 +106,25 @@ files:
81
106
  - things/user.sh/THING
82
107
  homepage: https://github.com/jordansissel/batcave
83
108
  licenses: []
109
+ metadata: {}
84
110
  post_install_message:
85
111
  rdoc_options: []
86
112
  require_paths:
87
113
  - lib
88
114
  required_ruby_version: !ruby/object:Gem::Requirement
89
- none: false
90
115
  requirements:
91
- - - ! '>='
116
+ - - ">="
92
117
  - !ruby/object:Gem::Version
93
118
  version: '0'
94
119
  required_rubygems_version: !ruby/object:Gem::Requirement
95
- none: false
96
120
  requirements:
97
- - - ! '>='
121
+ - - ">="
98
122
  - !ruby/object:Gem::Version
99
123
  version: '0'
100
124
  requirements: []
101
125
  rubyforge_project:
102
- rubygems_version: 1.8.24
126
+ rubygems_version: 2.2.2
103
127
  signing_key:
104
- specification_version: 3
128
+ specification_version: 4
105
129
  summary: Experiments in tools, boilerplatery, debugging, etc.
106
130
  test_files: []
107
- has_rdoc: