fue 0.1.2 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 72a7e11f7580c260950fb8f48393fe791cfdf1261c3d32afd97ceb76d87a8e64
4
- data.tar.gz: 97998c5b26b45a9dbbae295a930764bdc08ee9d394f109dd3166f82ef8542dca
3
+ metadata.gz: 6784a7e45c93b1e0622f4e719f58c541246a15fd64927245c97bd0f03574252a
4
+ data.tar.gz: ce2c2b1ef2f06c9cdd56d638ab4bbd7df8e1497ffb26190514d1e4b9f0ab621f
5
5
  SHA512:
6
- metadata.gz: cc2b85d03975f63b4328abc85aa39416c4e739b0d67f07087242e85b5a87df1585c99550350365a184d670cbef550fc3c92ca36b00ef1b1da39969ee2300b842
7
- data.tar.gz: 2a29212ce1dde69ed9ed1639a0d2c137ba682d3cacb3217ff935bc0636e1e244d9d3d5e98b0788ed17c149b400865f5edda22befeec18a0bb8319dc31ce7070f
6
+ metadata.gz: d503619065aab23dfd208305f1aafd9b8869538662397e6e471008be90c9713d510ac6e6af3ac5bfe2f1c392514749fa7eee8bd175aac2604da6e2223bb41ff4
7
+ data.tar.gz: 4d9ee34e80d5d031b291c4318fdab7733f95a5f5cf19e956078212b0a83e3700f54ee0e5227ee1635dcc2e0169e3d2a74d605a5db118f42d061e3ff0f17631b5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
- ### 0.1.2 (Next)
1
+ ### 0.3.1 (Next)
2
2
 
3
+ * [#29](https://github.com/dblock/fue/issues/29): Fix: `error: can't modify frozen String` - [@dblock](https://github.com/dblock).
4
+
5
+ ### 0.3.0 (2020/05/22)
6
+
7
+ * [#25](https://github.com/dblock/fue/pull/25): Added `contributors`, find repo contributors' e-mails - [@dblock](https://github.com/dblock).
8
+ * [#12](https://github.com/dblock/fue/issues/12): Added explicit ruby call to run fue - [@SYNstack](https://github.com/SYNstack).
9
+ * [#13](https://github.com/dblock/fue/issues/13): Changed shell tests to be OS-neutral - [@SYNstack](https://github.com/SYNstack).
10
+ * [#16](https://github.com/dblock/fue/issues/16): Setup Windows CI - [@SYNstack](https://github.com/synstack).
11
+ * [#17](https://github.com/dblock/fue/issues/19): Fix open-ended dependencies in gemspec - [@SYNstack](https://github.com/synstack).
12
+
13
+ ### 0.2.1 (2018/8/23)
14
+
15
+ * [#2](https://github.com/dblock/fue/issues/2): Prompt to authenticate with Github - [@dblock](https://github.com/dblock).
16
+ * [#7](https://github.com/dblock/fue/issues/7): Display version - [@dblock](https://github.com/dblock).
17
+
18
+ ### 0.2.0 (2018/8/22)
19
+
20
+ * [#6](https://github.com/dblock/fue/issues/6): Configure max depth and breadth separately - [@dblock](https://github.com/dblock).
21
+ * [#5](https://github.com/dblock/fue/issues/5): Iterate over more than 100 repositories - [@dblock](https://github.com/dblock).
3
22
  * [#5](https://github.com/dblock/fue/issues/5): Fix error message and clarify max depth - [@dblock](https://github.com/dblock).
4
23
 
5
24
  ### 0.1.1 (2018/8/14)
data/CONTRIBUTING.md CHANGED
@@ -4,11 +4,11 @@ This project is work of [many contributors](https://github.com/dblock/fue/graphs
4
4
 
5
5
  You're encouraged to submit [pull requests](https://github.com/dblock/fue/pulls), [propose features and discuss issues](https://github.com/dblock/fue/issues).
6
6
 
7
- In the examples below, substitute your Github username for `contributor` in URLs.
7
+ In the examples below, substitute your GitHub username for `contributor` in URLs.
8
8
 
9
9
  ### Fork the Project
10
10
 
11
- Fork the [project on Github](https://github.com/dblock/fue) and check out your copy.
11
+ Fork the [project on GitHub](https://github.com/dblock/fue) and check out your copy.
12
12
 
13
13
  ```
14
14
  git clone https://github.com/contributor/fue.git
@@ -47,7 +47,7 @@ We definitely appreciate pull requests that highlight or reproduce a problem, ev
47
47
 
48
48
  Implement your feature or bug fix.
49
49
 
50
- Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop). Run `bundle exec rubocop` and fix any style issues highlighted, auto-correct issues when possible with `bundle exec rubocop -a`. To silence generally ingored issues, including line lengths or code complexity metrics, run `bundle exec rubocop --auto-gen-config`.
50
+ Ruby style is enforced with [Rubocop](https://github.com/bbatsov/rubocop). Run `bundle exec rubocop` and fix any style issues highlighted, auto-correct issues when possible with `bundle exec rubocop -a`. To silence generally ignored issues, including line lengths or code complexity metrics, run `bundle exec rubocop --auto-gen-config`.
51
51
 
52
52
  Make sure that `bundle exec rake` completes without errors.
53
53
 
data/LICENSE.md CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2018 Daniel Doubrovkine.
3
+ Copyright (c) 2018-2020 Daniel Doubrovkine.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -3,8 +3,11 @@ Fue
3
3
 
4
4
  [![Gem Version](https://badge.fury.io/rb/fue.svg)](https://badge.fury.io/rb/fue)
5
5
  [![Build Status](https://travis-ci.org/dblock/fue.svg)](https://travis-ci.org/dblock/fue)
6
+ [![Build status](https://ci.appveyor.com/api/projects/status/github/dblock/fue?branch=master&svg=true)](https://ci.appveyor.com/project/dblock/fue)
6
7
 
7
- Find an e-mail address of a Github user from their commit log.
8
+ Find e-mail addresses of a Github users from their commit logs.
9
+
10
+ Fue is short for "Finding Unicorn Engineers".
8
11
 
9
12
  ![](images/fue.gif)
10
13
 
@@ -14,34 +17,45 @@ Find an e-mail address of a Github user from their commit log.
14
17
  gem install fue
15
18
  ```
16
19
 
17
- #### Get a Github Access Token
18
-
19
- Obtain a Github access token from [here](https://github.com/settings/tokens) with `public_repo` permissions. See [help](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line) for more information. Set the token as `GITHUB_ACCESS_TOKEN`.
20
+ ### Commands
20
21
 
21
22
  #### Find Someone's Email
22
23
 
23
- The `find` command looks through user's initial repo commits.
24
+ The `find` command looks through user's initial repository commits.
24
25
 
25
26
  ```
26
- GITHUB_ACCESS_TOKEN=token fue find defunkt
27
+ $ fue --verbose find defunkt
27
28
 
28
29
  Chris Wanstrath <chris@ozmm.org>
29
30
  Chris Wanstrath <chris@github.com>
30
31
  ```
31
32
 
33
+ #### Find All Repo Contributors' Emails
34
+
35
+ The `contributors` command looks through a git log of contributors, then fetches their e-mails.
36
+
37
+ ```
38
+ $ fue --verbose contributors defunkt/colored
39
+
40
+ defunkt: Chris Wanstrath <chris@ozmm.org>
41
+ kch: Caio Chassot <kch@users.noreply.github.com>
42
+ ```
43
+
44
+ ### Options
45
+
32
46
  #### Specify More Depth
33
47
 
34
- By default the code looks at the last 10 repos. You can have more depth, up to 100 (a limit enforced by Github).
48
+ By default the code looks at 1 commit from the last 10 repositories. You can look at more repositories (breadth) and more commits (depth). The maximum value for depth is 100, enforced by Github. Fue will iterate over a number of repositories larger than 100.
35
49
 
36
50
  ```
37
- GITHUB_ACCESS_TOKEN=token fue find --depth=100 defunkt
51
+ $ fue find --breadth=100 --depth=5 defunkt
38
52
 
39
53
  Chris Wanstrath <chris@ozmm.org>
40
54
  Chris Wanstrath <chris@github.com>
41
55
  defunkt <chris@ozmm.org>
42
56
  ```
43
57
 
44
- #### Get Help
58
+ ### Get Help
45
59
 
46
60
  ```
47
61
  fue help
@@ -49,12 +63,41 @@ fue help
49
63
 
50
64
  Displays additional options.
51
65
 
66
+ ### Access Tokens
67
+
68
+ Fue will prompt you for Github credentials and 2FA, if enabled.
69
+
70
+ ```
71
+ $ fue find defunkt
72
+ Enter dblock's GitHub password (never stored): ******************
73
+ Enter GitHub 2FA code: ******
74
+ Token saved to keychain.
75
+ ```
76
+
77
+ The access token will be generated with `public_repo` scope and stored in the keychain. It can be later deleted from [here](https://github.com/settings/tokens). You can also skip the prompts and use a previously obtained token with `-t` or by setting the `GITHUB_ACCESS_TOKEN` environment variable.
78
+
79
+ See [Creating a Personal Access Token for the Command Line](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line) for more information about personal tokens.
80
+
81
+ ## Debugging
82
+
83
+ If you run into an unexpected error, try getting a stack trace with `GLI_DEBUG=true`.
84
+
85
+ ```
86
+ $ GLI_DEBUG=true fue find dblock
87
+
88
+ FrozenError: can't modify frozen String
89
+ /Users/dblock/source/dblock/fue/lib/fue/auth.rb:97:in `get_secure'
90
+ /Users/dblock/source/dblock/fue/lib/fue/auth.rb:80:in `get_password'
91
+ /Users/dblock/source/dblock/fue/lib/fue/auth.rb:50:in `password'
92
+ /Users/dblock/source/dblock/fue/lib/fue/auth.rb:59:in `block in github'
93
+ ```
94
+
52
95
  ## Contributing
53
96
 
54
- There're [a few feature requests and known issues](https://github.com/dblock/fue/issues). Please contribute! See [CONTRIBUTING](CONTRIBUTING.md).
97
+ There are [a few feature requests and known issues](https://github.com/dblock/fue/issues). Please contribute! See [CONTRIBUTING](CONTRIBUTING.md).
55
98
 
56
99
  ## Copyright and License
57
100
 
58
- Copyright (c) 2018, Daniel Doubrovkine, [Artsy](http://artsy.github.io), with help from [Orta](https://github.com/orta).
101
+ Copyright (c) 2018-2020, Daniel Doubrovkine, [Artsy](http://artsy.github.io), with help from [Orta](https://github.com/orta).
59
102
 
60
103
  This project is licensed under the [MIT License](LICENSE.md).
data/bin/fue CHANGED
@@ -1,35 +1,67 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
2
4
  require 'gli'
3
5
  require 'fue'
4
- require 'graphlient'
5
6
 
6
7
  class App
7
8
  extend GLI::App
8
9
 
9
- program_desc "Find a Github user's e-mail address."
10
+ program_desc "Find a GitHub user's e-mail address."
11
+ version Fue::VERSION
10
12
 
11
13
  switch %i[v verbose], desc: 'Produce verbose output.', default_value: false
12
- flag %i[t token], desc: 'Github access token.', default_value: ENV['GITHUB_ACCESS_TOKEN']
14
+ flag %i[t token], desc: 'GitHub access token.', default_value: ENV['GITHUB_ACCESS_TOKEN']
15
+ flag %i[u username], desc: 'GitHub username.', default_value: Fue::Auth.instance.username
13
16
 
14
17
  arguments :strict
15
18
  subcommand_option_handling :normal
16
19
 
17
20
  pre do |global_options, _command, options, _args|
18
21
  options = global_options.dup
19
- token = options.delete(:token)
22
+ token = options.delete(:token) || Fue::Auth.instance.token
20
23
  $fue = Fue::Finder.new(token, options)
21
24
  end
22
25
 
23
26
  default_command :help
24
27
 
25
- desc "Find a Github user's e-mail address."
28
+ desc "Find a GitHub user's e-mail address."
26
29
  arg 'username'
27
30
  command :find do |c|
28
- c.flag %i[d depth], desc: 'Maximum search depth.', default_value: 10
31
+ c.flag %i[d depth], desc: 'Maximum search depth in each repository.', default_value: 1
32
+ c.flag %i[b breadth], desc: 'Maximum number of repositories to search.', default_value: 10
29
33
  c.action do |global_options, options, args|
30
34
  username = args.first
31
- puts "Searching for e-mail address for '#{username}' at max depth of #{options[:depth]} ..." if global_options[:verbose]
32
- puts $fue.emails(options.merge(username: username))
35
+ options[:depth] = options[:depth].to_i
36
+ options[:breadth] = options[:breadth].to_i
37
+ if global_options[:verbose]
38
+ puts "Searching for e-mail address for '#{username}' " \
39
+ "in the first #{options[:depth].to_i > 1 ? "#{options[:depth]} commits" : 'commit'} " \
40
+ "of #{options[:breadth]} most recent repositor#{options[:breadth] == 1 ? 'y' : 'ies'} ..."
41
+ end
42
+ puts $fue.emails(options.merge(username: username, verbose: global_options[:verbose]))
43
+ exit_now! nil, 0
44
+ end
45
+ end
46
+
47
+ desc "Find a GitHub repo contributors' e-mail addresses."
48
+ arg 'repo'
49
+ command :contributors do |c|
50
+ c.flag %i[d depth], desc: 'Maximum search depth in each repository for a given user.', default_value: 1
51
+ c.flag %i[b breadth], desc: 'Maximum number of repositories to search.', default_value: 10
52
+ c.action do |global_options, options, args|
53
+ repo = args.first
54
+ options[:depth] = options[:depth].to_i
55
+ options[:breadth] = options[:breadth].to_i
56
+ if global_options[:verbose]
57
+ puts "Searching for contributors' e-mail addresses in '#{repo}' " \
58
+ "in the first #{options[:depth].to_i > 1 ? "#{options[:depth]} commits" : 'commit'} " \
59
+ "of #{options[:breadth]} most recent repositor#{options[:breadth] == 1 ? 'y' : 'ies'} ..."
60
+ end
61
+ contributor_emails = $fue.contributors(options.merge(repo: repo, verbose: global_options[:verbose]))
62
+ contributor_emails.each_pair do |username, emails|
63
+ puts "#{username}: #{emails.join(', ')}"
64
+ end
33
65
  exit_now! nil, 0
34
66
  end
35
67
  end
data/lib/fue.rb CHANGED
@@ -1,2 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphlient'
4
+ require 'github_api'
5
+ require 'open3'
6
+ require 'English'
7
+
1
8
  require 'fue/version'
9
+ require 'fue/shell'
2
10
  require 'fue/finder'
11
+ require 'fue/security'
12
+ require 'fue/auth'
data/lib/fue/auth.rb ADDED
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fue
4
+ class Auth
5
+ def self.instance
6
+ @instance ||= new
7
+ end
8
+
9
+ def token
10
+ stored_options = { username: username, server: 'github.com', label: 'fue' }
11
+ stored_token = Fue::Security.get(stored_options)
12
+ unless stored_token
13
+ stored_token = github_token
14
+ Fue::Security.store!(stored_options.merge(password: stored_token))
15
+ puts 'Token saved to keychain.'
16
+ end
17
+ stored_token
18
+ end
19
+
20
+ def username
21
+ @username ||= begin
22
+ username = get_git_username&.chomp
23
+ username = get_username if username.nil? || username.empty?
24
+ username
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def get_git_username
31
+ Fue::Shell.system!('git config user.name')
32
+ rescue RuntimeError
33
+ nil
34
+ end
35
+
36
+ def github_token(code = nil)
37
+ github(code).auth.create(scopes: ['public_repo'], note: note).token
38
+ rescue Github::Error::Unauthorized => e
39
+ case e.response_headers['X-GitHub-OTP']
40
+ when /required/
41
+ github_token(get_code)
42
+ else
43
+ raise e
44
+ end
45
+ rescue Github::Error::UnprocessableEntity => e
46
+ raise e, 'A fue token already exists! Please revoke all previously-generated fue personal access tokens at https://github.com/settings/tokens.'
47
+ end
48
+
49
+ def password
50
+ @password ||= get_password
51
+ end
52
+
53
+ def note
54
+ "Fui (https://github.com/dblock/fue) on #{Socket.gethostname}"
55
+ end
56
+
57
+ def github(code = nil)
58
+ Github.new do |config|
59
+ config.basic_auth = [username, password].join(':')
60
+ if code
61
+ config.connection_options = {
62
+ headers: {
63
+ 'X-GitHub-OTP' => code
64
+ }
65
+ }
66
+ end
67
+ end
68
+ end
69
+
70
+ def get_username
71
+ print 'Enter GitHub username: '
72
+ username = $stdin.gets
73
+ username&.chomp
74
+ rescue Interrupt => e
75
+ raise e, 'ctrl + c'
76
+ end
77
+
78
+ def get_password
79
+ print "Enter #{username}'s GitHub password (never stored): "
80
+ get_secure
81
+ end
82
+
83
+ def get_code
84
+ print 'Enter GitHub 2FA code: '
85
+ get_secure
86
+ end
87
+
88
+ def get_secure
89
+ current_tty = `stty -g`
90
+ system 'stty raw -echo -icanon isig' if $CHILD_STATUS.success?
91
+ input = String.new
92
+ while (char = $stdin.getbyte) && !((char == 13) || (char == 10))
93
+ if (char == 127) || (char == 8)
94
+ input[-1, 1] = '' unless input.empty?
95
+ else
96
+ $stdout.write '*'
97
+ input << char.chr
98
+ end
99
+ end
100
+ print "\r\n"
101
+ input
102
+ rescue Interrupt => e
103
+ raise e, 'ctrl + c'
104
+ ensure
105
+ system "stty #{current_tty}" unless current_tty.empty?
106
+ end
107
+ end
108
+ end
data/lib/fue/finder.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Fue
2
4
  class Finder
3
5
  attr_reader :token
@@ -19,20 +21,18 @@ module Fue
19
21
 
20
22
  def emails(options = {})
21
23
  query = <<-GRAPHQL
22
- query($login: String!, $author_id: ID!, $depth: Int!) {
24
+ query($login: String!, $author_id: ID!, $depth: Int!, $breadth: Int!, $cursor: String) {
23
25
  user(login: $login) {
24
- repositories(last: $depth, isFork:false, privacy: PUBLIC) {
25
- edges {
26
- node {
27
- defaultBranchRef {
28
- target {
29
- ... on Commit {
30
- history(first: 1, author: { id: $author_id }) {
31
- nodes {
32
- author {
33
- email
34
- name
35
- }
26
+ repositories(last: $breadth, after: $cursor, isFork:false, privacy: PUBLIC) {
27
+ nodes {
28
+ defaultBranchRef {
29
+ target {
30
+ ... on Commit {
31
+ history(first: $depth, author: { id: $author_id }) {
32
+ nodes {
33
+ author {
34
+ email
35
+ name
36
36
  }
37
37
  }
38
38
  }
@@ -40,23 +40,108 @@ module Fue
40
40
  }
41
41
  }
42
42
  }
43
+ pageInfo {
44
+ startCursor
45
+ }
43
46
  }
44
47
  }
45
48
  }
46
49
  GRAPHQL
47
50
 
51
+ # max number of repositories to search
52
+ max_breadth = options[:breadth] || 10
53
+
48
54
  query_options = {
49
55
  login: options[:username],
50
56
  author_id: author_id(options[:username]),
51
- depth: (options[:depth] || 10).to_i
57
+ # max number of commits to look into
58
+ depth: options[:depth] || 1
52
59
  }
53
60
 
54
- graphql_client.query(query, query_options).data.user.repositories.edges.map do |edge|
55
- next unless edge.node.default_branch_ref
56
- edge.node.default_branch_ref.target.history.nodes.map do |node|
57
- "#{node.author.name} <#{node.author.email}>"
61
+ $stdout.write "Searching for emails for #{options[:username]} ." if options[:verbose]
62
+
63
+ emails = Set.new
64
+
65
+ loop do
66
+ query_options[:breadth] = [max_breadth, 100].min
67
+ response = graphql_client.query(query, query_options)
68
+ repositories = response&.data&.user&.repositories
69
+ repositories&.nodes&.each do |history|
70
+ default_history = history.default_branch_ref&.target&.history
71
+ default_history&.nodes&.each do |node|
72
+ emails << "#{node.author.name} <#{node.author.email}>"
73
+ end
58
74
  end
59
- end.flatten.compact.uniq
75
+ query_options[:cursor] = repositories&.page_info&.start_cursor
76
+ break unless query_options[:cursor]
77
+
78
+ max_breadth -= 100
79
+ break if max_breadth <= 0
80
+
81
+ $stdout.write '.' if options[:verbose]
82
+ end
83
+
84
+ puts " found #{emails.size} email address#{emails.size == 1 ? '' : 'es'}." if options[:verbose]
85
+
86
+ emails.to_a
87
+ end
88
+
89
+ def contributors(options = {})
90
+ query = <<-GRAPHQL
91
+ query($owner: String!, $name: String!, $cursor: String) {
92
+ repository(owner: $owner, name: $name) {
93
+ defaultBranchRef {
94
+ target {
95
+ ... on Commit {
96
+ history(first: 100, after: $cursor) {
97
+ nodes {
98
+ author {
99
+ user {
100
+ login
101
+ }
102
+ }
103
+ }
104
+ pageInfo {
105
+ endCursor
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ GRAPHQL
114
+
115
+ repo_owner, repo_name = options[:repo].split('/', 2)
116
+
117
+ query_options = {
118
+ owner: repo_owner,
119
+ name: repo_name
120
+ }
121
+
122
+ logins = Set.new
123
+
124
+ $stdout.write 'Fetching contributors .' if options[:verbose]
125
+
126
+ loop do
127
+ response = graphql_client.query(query, query_options)
128
+ history = response&.data&.repository&.default_branch_ref&.target&.history
129
+ history&.nodes&.each do |node|
130
+ login = node.author.user&.login
131
+ logins << login if login
132
+ end
133
+ query_options[:cursor] = history&.page_info.end_cursor
134
+ $stdout.write '.' if options[:verbose]
135
+ break unless query_options[:cursor]
136
+ end
137
+
138
+ puts " found #{logins.size} contributor#{logins.size == 1 ? '' : 's'}." if options[:verbose]
139
+
140
+ logins.map do |login|
141
+ [login, emails(options.merge(username: login))]
142
+ rescue StandardError => e
143
+ warn e.to_s
144
+ end.compact.to_h
60
145
  end
61
146
 
62
147
  private
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fue
4
+ module Security
5
+ class << self
6
+ def store!(options)
7
+ Fue::Shell.system!(security('add', options))
8
+ end
9
+
10
+ def get(options)
11
+ Fue::Shell.system!(security('find', options))
12
+ rescue RuntimeError
13
+ nil
14
+ end
15
+
16
+ private
17
+
18
+ def security(command = nil, options = nil)
19
+ run = [security_path]
20
+ run << "#{command}-internet-password"
21
+ run << "-a #{options[:username]}"
22
+ run << "-s #{options[:server]}"
23
+ if command == 'add'
24
+ run << "-l #{options[:label]}"
25
+ run << '-U'
26
+ run << "-w #{options[:password]}" if options.key?(:password)
27
+ else
28
+ run << '-w'
29
+ end
30
+ run.join ' '
31
+ end
32
+
33
+ def security_path
34
+ @security_path ||= begin
35
+ `which security`.chomp
36
+ rescue StandardError
37
+ 'security'
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
data/lib/fue/shell.rb ADDED
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fue
4
+ module Shell
5
+ class << self
6
+ def system!(*cmd)
7
+ stdout, stderr, status = Open3.capture3(*cmd)
8
+ raise ["exit code #{status}", stderr].compact.join("\n") unless status.success?
9
+
10
+ stdout.slice!(0..-(1 + $INPUT_RECORD_SEPARATOR.size))
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/fue/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Fue
2
- VERSION = '0.1.2'.freeze
4
+ VERSION = '0.3.1'
3
5
  end
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Doubrovkine
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-18 00:00:00.000000000 Z
11
+ date: 2021-07-19 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: github_api
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.18.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.18.2
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: gli
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - ">="
31
+ - - "~>"
18
32
  - !ruby/object:Gem::Version
19
- version: '0'
33
+ version: '2.17'
20
34
  type: :runtime
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - ">="
38
+ - - "~>"
25
39
  - !ruby/object:Gem::Version
26
- version: '0'
40
+ version: '2.17'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: graphlient
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,7 +52,7 @@ dependencies:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
54
  version: 0.3.2
41
- description:
55
+ description:
42
56
  email: dblock@dblock.org
43
57
  executables:
44
58
  - fue
@@ -51,13 +65,16 @@ files:
51
65
  - README.md
52
66
  - bin/fue
53
67
  - lib/fue.rb
68
+ - lib/fue/auth.rb
54
69
  - lib/fue/finder.rb
70
+ - lib/fue/security.rb
71
+ - lib/fue/shell.rb
55
72
  - lib/fue/version.rb
56
73
  homepage: http://github.com/dblock/fue
57
74
  licenses:
58
75
  - MIT
59
76
  metadata: {}
60
- post_install_message:
77
+ post_install_message:
61
78
  rdoc_options: []
62
79
  require_paths:
63
80
  - lib
@@ -65,16 +82,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
82
  requirements:
66
83
  - - ">="
67
84
  - !ruby/object:Gem::Version
68
- version: '0'
85
+ version: '2.5'
69
86
  required_rubygems_version: !ruby/object:Gem::Requirement
70
87
  requirements:
71
88
  - - ">="
72
89
  - !ruby/object:Gem::Version
73
90
  version: 1.3.6
74
91
  requirements: []
75
- rubyforge_project:
76
- rubygems_version: 2.7.6
77
- signing_key:
92
+ rubygems_version: 3.0.4
93
+ signing_key:
78
94
  specification_version: 4
79
- summary: Find an e-mail address of a Github user.
95
+ summary: Find an e-mail address of a GitHub user.
80
96
  test_files: []