Module: GitRelease

Defined in:
lib/git-release.rb,
lib/git-release/version.rb

Constant Summary collapse

VERSION =
"0.0.7"

Class Method Summary collapse

Class Method Details

.add_doc(repo, tag, text) ⇒ Object



314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
# File 'lib/git-release.rb', line 314

def self.add_doc(repo, tag, text)
    client = get_api_client
    releases = client.releases(repo)
    release = get_tag(releases, tag)

    if text.kind_of?(Array)
        text = text.join("\n")
    end
    if release.body.nil? or release.body.empty?
        body = text
    else
        body = "#{release.body}\n#{text}"
    end
    client.update_release(release.url, :body => body)
end

.ask_note(note) ⇒ Object



153
154
155
156
157
158
159
# File 'lib/git-release.rb', line 153

def self.ask_note(note)
    note = $cli.ask("OAuth token note: ", String) { |q| q.default = note }
    if note.empty?
        exit 1
    end
    note
end

.ask_otpObject



145
146
147
148
149
150
151
# File 'lib/git-release.rb', line 145

def self.ask_otp
    otp = $cli.ask("GitHub 2FA: ", String)
    if otp.empty?
        exit 1
    end
    otp
end

.ask_passwordObject



137
138
139
140
141
142
143
# File 'lib/git-release.rb', line 137

def self.ask_password
    pass = $cli.ask("GitHub Password: ", String) { |q| q.echo = "*" }
    if pass.empty?
        exit 1
    end
    pass
end

.ask_usernameObject



129
130
131
132
133
134
135
# File 'lib/git-release.rb', line 129

def self.ask_username
    user = $cli.ask("GitHub User: ", String)
    if user.empty?
        exit 1
    end
    user
end

.choose_delete(client, note) ⇒ Object



191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/git-release.rb', line 191

def self.choose_delete(client, note)
    $cli.choose do |menu|
        menu.prompt = "Token '#{note}' already exists: "
        menu.choice("regenerate token (will delete old one)") do
            delete_token(client, note)
            note
        end
        menu.choice("generate token with new name") do
            ask_note(note)
        end
    end
end

.clear_doc(repo, tag) ⇒ Object



307
308
309
310
311
312
# File 'lib/git-release.rb', line 307

def self.clear_doc(repo, tag)
    client = get_api_client
    releases = client.releases(repo)
    release = get_tag(releases, tag)
    client.update_release(release.url, :body => "")
end

.delete_token(client, note) ⇒ Object



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/git-release.rb', line 161

def self.delete_token(client, note)
    otp = ""
    id = ""
    done = false
    while !done do
        begin
            if id.empty?
                if otp.empty?
                    auths = client.authorizations
                else
                    auths = client.authorizations(
                        :headers => { "X-GitHub-OTP" => otp})
                end
                id = auths.find { |a| a.note.include?(note) }.id
            else
                if otp.empty?
                    client.delete_authorization(id)
                else
                    client.delete_authorization(
                        id,
                        :headers => { "X-GitHub-OTP" => otp})
                end
                done = true
            end
        rescue Octokit::OneTimePasswordRequired => e
            otp = ask_otp
        end
    end
end

.do_loginObject



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/git-release.rb', line 97

def self.
    if File.file?(File.expand_path($token_file))
        begin
            test = get_api_client
            test.repos
        rescue
            client = get_user_client
            token = get_token(client)
            store_token(token)
        end
    else
        client = get_user_client
        token = get_token(client)
        store_token(token)
    end
end

.get_api_clientObject



87
88
89
# File 'lib/git-release.rb', line 87

def self.get_api_client
    Octokit::Client.new(:access_token => load_token)
end

.get_repoObject



75
76
77
78
79
80
81
82
83
84
85
# File 'lib/git-release.rb', line 75

def self.get_repo
    repo = `git remote get-url origin`.
        sub("\n", "").
        gsub(/.*github.com./, "")
    if $?.exitstatus == 0
        repo
    else
        puts "not a git repository"
        exit 1
    end
end

.get_tag(releases, tag) ⇒ Object



276
277
278
279
280
281
282
283
# File 'lib/git-release.rb', line 276

def self.get_tag(releases, tag)
    release = releases.find { |r| r.tag_name == tag }
    if release.empty?
        puts "unknown tag #{tag}"
        exit 1
    end
    release
end

.get_token(client) ⇒ Object



204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/git-release.rb', line 204

def self.get_token(client)
    token = ""
    note = 'Git Release CLI',
    otp = ""
    while token.empty? do
        begin
            if otp.empty?
                token = client.create_authorization(
                    :scopes => ['repo'],
                    :note => note)
            else
                token = client.create_authorization(
                    :scopes => ['repo'],
                    :note => note,
                    :headers => { "X-GitHub-OTP" => otp})
            end
        rescue Octokit::OneTimePasswordRequired => e
            otp = ask_otp
        rescue Octokit::UnprocessableEntity => e
            if e.message.include?("already_exists")
                note = choose_delete(client, note)
            else
                puts e
                exit 1
            end
        rescue => e
            puts e
            exit 1
        end
    end
    token.token
end

.get_user_clientObject



91
92
93
94
95
# File 'lib/git-release.rb', line 91

def self.get_user_client
    user = ask_username
    pass = ask_password
    client = Octokit::Client.new(:login => user, :password => pass)
end

.load_tokenObject



114
115
116
117
118
119
120
121
# File 'lib/git-release.rb', line 114

def self.load_token
    begin
        File.open(File.expand_path($token_file), &:readline)
    rescue
        puts "please login first"
        exit 1
    end
end


237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
# File 'lib/git-release.rb', line 237

def self.print_releases(repo)
    client = get_api_client
    releases = client.releases(repo)
    sorted = releases.sort { |x,y| y.created_at <=> x.created_at }
    first_testing = first_production = true
    sorted.each do |r|
        if r.draft
            $cli.say("<%= color('#{r.tag_name} (draft)', :red) %>")
        elsif r.prerelease
            $cli.say("<%= color('#{r.tag_name} (prerelease)', :yellow) %>")
            if first_testing
                $cli.say("<%= color('current testing', :blue) %>")
                first_testing = false
            end
        else
            $cli.say("<%= color('#{r.tag_name} (release)', :green) %>")
            if first_testing and first_production
                $cli.say("<%= color('current testing and production', :blue) %>")
                first_testing = first_production = false
            elsif first_production
                $cli.say("<%= color('current production', :blue) %>")
                first_production = false
            end
        end

        $cli.say("<%= color('released:', :blue) %> #{r.published_at}")
        if !r.body.nil? and !r.body.empty?
            $cli.say("<%= color('notes:', :blue) %>")
            r.body.each_line { |l| $cli.say("  #{l}") }
        end
        puts
    end
    if first_production and first_testing
        $cli.say("<%= color('no release for testing and production!', :red) %>")
    elsif first_production
        $cli.say("<%= color('no release for production!', :red) %>")
    end
end

.run(args) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/git-release.rb', line 17

def self.run(args)
    args << 'help' if args.empty?
    command = args.shift

    case command
    when 'help'
        usage
    when 'version'
        version
    when 'login'
         = 
        puts 'successfully logged in'
    when 'list'
        repo = get_repo
        print_releases(repo)
    when 'set'
        repo = get_repo
        tag = args.shift
        status = $status[args.shift] || unknown_status
        set_release(repo, tag, status)
    when 'doc'
        repo = get_repo
        task = args.shift
        tag = args.shift
        case task
        when 'clear'
            clear_doc(repo, tag)
        when 'add'
            add_doc(repo, tag, args)
        end
    end
end

.set_release(repo, tag, status) ⇒ Object



285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
# File 'lib/git-release.rb', line 285

def self.set_release(repo, tag, status)
    client = get_api_client
    releases = client.releases(repo)
    release = get_tag(releases, tag)
    case status
    when "release"
        prerelease = false
        draft = false
    when "prerelease"
        prerelease = true
        draft = false
    when "draft"
        prerelease = true
        draft = true
    end

    client.update_release(
        release.url,
        :prerelease => prerelease,
        :draft => draft)
end

.store_token(token) ⇒ Object



123
124
125
126
127
# File 'lib/git-release.rb', line 123

def self.store_token(token)
    f = File.new(File.expand_path($token_file), 'w', 0600)
    f.write(token)
    f.close
end

.unknown_statusObject



69
70
71
72
73
# File 'lib/git-release.rb', line 69

def self.unknown_status
    puts "unknown status"
    puts "use one of: r[elease], p[rerelease] or d[raft]"
    exit 1
end

.usageObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/git-release.rb', line 50

def self.usage
    puts "usage: git release <command> [<args>]"
    puts ""
    puts "These are the available commands:"
    puts " help                 print this message"
    puts " version              print the current version"
    puts " login                create or verify api token"
    puts " list                 list all releases"
    puts " set <tag> <state>    change the status of a release"
    puts "     tag              tag of the release to change"
    puts "     state            new state. either r[elease], p[rerelease] or d[raft]"
    puts " doc clear <tag>      clear the release notes"
    puts " doc add <tag> <text> add one or more lines to the release notes"
end

.versionObject



65
66
67
# File 'lib/git-release.rb', line 65

def self.version
    puts "git-release version #{GitRelease::VERSION}"
end