geordi 11.1.0 → 11.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +2 -0
- data/CHANGELOG.md +13 -1
- data/Gemfile.lock +6 -6
- data/README.md +25 -17
- data/lib/geordi/commands/branch.rb +1 -1
- data/lib/geordi/commands/deploy.rb +7 -3
- data/lib/geordi/commands/security_update.rb +10 -25
- data/lib/geordi/gitlinear.rb +37 -37
- data/lib/geordi/interaction.rb +2 -0
- data/lib/geordi/settings.rb +8 -3
- data/lib/geordi/util.rb +13 -1
- data/lib/geordi/version.rb +1 -1
- data/media/logo.dark.shapes.svg +125 -0
- data/media/logo.dark.text.svg +107 -0
- data/media/logo.light.shapes.svg +124 -0
- data/media/logo.light.text.svg +106 -0
- data/media/makandra-with-bottom-margin.dark.svg +180 -0
- data/media/makandra-with-bottom-margin.light.svg +180 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 777831ce74c67b2be9515af1f7d1ba265a7ff57b081d6b02252f573a313caaa7
|
4
|
+
data.tar.gz: 0a39b24e79c1fe603acee2e66445542cba13bf807419f18aa13edf64386d5705
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: baea0e5dba392efd9a23d19ba910392567d37c5d9502a0adfa7e9cb7d45dadbfccff78abc4144863718fdeea2ffe1da0b076a275877ef0b82a463a7246328611
|
7
|
+
data.tar.gz: 68e5f0383171b8c1f8315e1c13828f9aa78f1e4c06b1e62df35e9f2519b0f0c78c66d07228da3c71e50c7eb3fe07ae14e7a4f9d31aedd652f960c5d8a00a3373
|
data/.github/workflows/test.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -7,12 +7,24 @@ This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html
|
|
7
7
|
|
8
8
|
### Compatible changes
|
9
9
|
|
10
|
+
- Add support for Ruby 3.3
|
11
|
+
|
10
12
|
### Breaking changes
|
11
13
|
|
12
|
-
|
14
|
+
|
15
|
+
## 11.2.0 2024-11-22
|
13
16
|
|
14
17
|
### Compatible changes
|
18
|
+
* Add support for default branches other than "master" (e.g. "main"). Will read
|
19
|
+
this information from `origin`.
|
20
|
+
* `geordi branch` will not fail if it can't determine local branches.
|
21
|
+
* Improved Linear issue menu: now includes the issue id, truncates long issue
|
22
|
+
titles and puts metadata last
|
23
|
+
|
15
24
|
|
25
|
+
## 11.1.0 2024-11-20
|
26
|
+
|
27
|
+
### Compatible changes
|
16
28
|
* Skip `yarn install` for other package managers:
|
17
29
|
* Before: Check for a `package.json`
|
18
30
|
* After: Check for a `yarn.lock`
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
geordi (11.1
|
4
|
+
geordi (11.2.1)
|
5
5
|
thor (~> 1)
|
6
6
|
|
7
7
|
GEM
|
@@ -63,7 +63,7 @@ GEM
|
|
63
63
|
concurrent-ruby (~> 1.0)
|
64
64
|
launchy (2.4.3)
|
65
65
|
addressable (~> 2.3)
|
66
|
-
method_source (1.
|
66
|
+
method_source (1.1.0)
|
67
67
|
middleware (0.1.0)
|
68
68
|
minitest (5.14.4)
|
69
69
|
multi_test (0.1.2)
|
@@ -75,12 +75,12 @@ GEM
|
|
75
75
|
middleware
|
76
76
|
thor
|
77
77
|
thread_safe
|
78
|
-
pry (0.
|
78
|
+
pry (0.14.2)
|
79
79
|
coderay (~> 1.1)
|
80
80
|
method_source (~> 1.0)
|
81
|
-
pry-byebug (3.
|
81
|
+
pry-byebug (3.10.1)
|
82
82
|
byebug (~> 11.0)
|
83
|
-
pry (
|
83
|
+
pry (>= 0.13, < 0.15)
|
84
84
|
public_suffix (3.1.1)
|
85
85
|
rake (12.3.3)
|
86
86
|
rspec (3.10.0)
|
@@ -119,4 +119,4 @@ DEPENDENCIES
|
|
119
119
|
rspec
|
120
120
|
|
121
121
|
BUNDLED WITH
|
122
|
-
2.3.
|
122
|
+
2.3.26
|
data/README.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
<p>
|
2
|
+
<a href="https://makandra.de/">
|
3
|
+
<picture>
|
4
|
+
<source media="(prefers-color-scheme: light)" srcset="media/makandra-with-bottom-margin.light.svg">
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="media/makandra-with-bottom-margin.dark.svg">
|
6
|
+
<img align="right" width="25%" alt="makandra" src="media/makandra-with-bottom-margin.light.svg">
|
7
|
+
</picture>
|
8
|
+
</a>
|
9
|
+
|
10
|
+
<picture>
|
11
|
+
<source media="(prefers-color-scheme: light)" srcset="media/logo.light.shapes.svg">
|
12
|
+
<source media="(prefers-color-scheme: dark)" srcset="media/logo.dark.shapes.svg">
|
13
|
+
<img width="140" alt="Geordi" role="heading" aria-level="1" src="media/logo.light.shapes.svg">
|
14
|
+
</picture>
|
15
|
+
</p>
|
16
|
+
|
17
|
+
[![Tests](https://github.com/makandra/geordi/workflows/Tests/badge.svg)](https://github.com/makandra/geordi/actions)
|
18
|
+
|
3
19
|
|
4
20
|
Geordi is a collection of command line tools we use in our daily work with
|
5
21
|
Ruby, Rails and Linux at [makandra](http://makandra.com/).
|
@@ -32,7 +48,7 @@ On the first execution we ask for your Linear API token. It will be
|
|
32
48
|
stored in `~/.config/geordi/global.yml`.
|
33
49
|
|
34
50
|
**Options**
|
35
|
-
- `-m, [--from-master], [--no-from-master]`: Branch from master instead of the current branch
|
51
|
+
- `-m, --from-main, [--from-master], [--no-from-master]`: Branch from master instead of the current branch
|
36
52
|
|
37
53
|
|
38
54
|
### `geordi capistrano COMMAND`
|
@@ -142,7 +158,8 @@ before it does it.** There are different scenarios where this command is handy:
|
|
142
158
|
be skipped.
|
143
159
|
|
144
160
|
Calling the command without arguments will infer the target stage from the
|
145
|
-
current branch and fall back to master/staging.
|
161
|
+
current branch and fall back to master/staging. (Will use the actual main branch
|
162
|
+
of the repository, e.g. "main" instead of "master".)
|
146
163
|
|
147
164
|
Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
|
148
165
|
deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
|
@@ -267,29 +284,20 @@ variable like this: `PARALLEL_TEST_PROCESSORS=6 geordi rspec`
|
|
267
284
|
Support for performing security updates.
|
268
285
|
|
269
286
|
Preparation for security update: `geordi security-update`. Checks out production
|
270
|
-
and pulls.
|
287
|
+
and pulls, and will tell each step before performing it.
|
271
288
|
|
272
|
-
|
273
|
-
pulls, pushes and deploys as required by our workflow.
|
274
|
-
|
275
|
-
This command tells what it will do before it does it. In detail:
|
289
|
+
Part two after performing the update: `geordi security-update finish`. Switches
|
290
|
+
branches, pulls, pushes and deploys as required by our workflow. This as well
|
291
|
+
will tell each step before performing it. In detail:
|
276
292
|
|
277
293
|
1. Ask user if tests are green
|
278
|
-
|
279
294
|
2. Push production
|
280
|
-
|
281
295
|
3. Check out master and pull
|
282
|
-
|
283
296
|
4. Merge production and push in master
|
284
|
-
|
285
297
|
5. Deploy staging, if there is a staging environment
|
286
|
-
|
287
298
|
6. Ask user if deployment log is okay and staging application is still running
|
288
|
-
|
289
299
|
7. Deploy other stages
|
290
|
-
|
291
300
|
8. Ask user if deployment log is okay and application is still running on all stages
|
292
|
-
|
293
301
|
9. Inform user about the next (manual) steps
|
294
302
|
|
295
303
|
|
@@ -6,7 +6,7 @@ On the first execution we ask for your Linear API token. It will be
|
|
6
6
|
stored in `~/.config/geordi/global.yml`.
|
7
7
|
LONGDESC
|
8
8
|
|
9
|
-
option :from_master, aliases:
|
9
|
+
option :from_master, aliases: %w[-m --from-main], type: :boolean, desc: 'Branch from master instead of the current branch'
|
10
10
|
|
11
11
|
def branch
|
12
12
|
require 'geordi/gitlinear'
|
@@ -19,7 +19,8 @@ before it does it.** There are different scenarios where this command is handy:
|
|
19
19
|
be skipped.
|
20
20
|
|
21
21
|
Calling the command without arguments will infer the target stage from the
|
22
|
-
current branch and fall back to master/staging.
|
22
|
+
current branch and fall back to master/staging. (Will use the actual main branch
|
23
|
+
of the repository, e.g. "main" instead of "master".)
|
23
24
|
|
24
25
|
Finds available Capistrano stages by their prefix, e.g. `geordi deploy p` will
|
25
26
|
deploy production, `geordi deploy mak` will deploy a `makandra` stage if there
|
@@ -37,7 +38,7 @@ option :current_branch, aliases: '-c', type: :boolean,
|
|
37
38
|
|
38
39
|
def deploy(target_stage = nil)
|
39
40
|
# Set/Infer default values
|
40
|
-
branch_stage_map = { 'master' => 'staging', 'production' => 'production' }
|
41
|
+
branch_stage_map = { 'master' => 'staging', 'main' => 'staging', 'production' => 'production' }
|
41
42
|
if target_stage && !Util.deploy_targets.include?(target_stage)
|
42
43
|
# Target stage autocompletion from available stages
|
43
44
|
target_stage = Util.deploy_targets.find { |t| t.start_with? target_stage }
|
@@ -58,7 +59,10 @@ def deploy(target_stage = nil)
|
|
58
59
|
source_branch = target_branch = Util.current_branch
|
59
60
|
else
|
60
61
|
source_branch = Interaction.prompt 'Source branch:', Util.current_branch
|
61
|
-
|
62
|
+
|
63
|
+
deploy_branch = 'production' if target_stage == 'production'
|
64
|
+
deploy_branch ||= Util.git_default_branch
|
65
|
+
target_branch = Interaction.prompt 'Deploy branch:', deploy_branch
|
62
66
|
end
|
63
67
|
|
64
68
|
merge_needed = (source_branch != target_branch)
|
@@ -1,33 +1,16 @@
|
|
1
1
|
desc 'security-update [STEP]', 'Support for performing security updates'
|
2
2
|
long_desc <<-LONGDESC
|
3
3
|
Preparation for security update: `geordi security-update`. Checks out production
|
4
|
-
and pulls.
|
4
|
+
and pulls, and will tell each step before performing it.
|
5
5
|
|
6
|
-
|
7
|
-
pulls, pushes and deploys as required by our workflow.
|
8
|
-
|
9
|
-
This command tells what it will do before it does it. In detail:
|
10
|
-
|
11
|
-
1. Ask user if tests are green
|
12
|
-
|
13
|
-
2. Push production
|
14
|
-
|
15
|
-
3. Check out master and pull
|
16
|
-
|
17
|
-
4. Merge production and push in master
|
18
|
-
|
19
|
-
5. Deploy staging, if there is a staging environment
|
20
|
-
|
21
|
-
6. Ask user if deployment log is okay and staging application is still running
|
22
|
-
|
23
|
-
7. Deploy other stages
|
24
|
-
|
25
|
-
8. Ask user if deployment log is okay and application is still running on all stages
|
26
|
-
|
27
|
-
9. Inform user about the next (manual) steps
|
6
|
+
Part two after performing the update: `geordi security-update finish`. Switches
|
7
|
+
branches, pulls, pushes and deploys as required by our workflow. This as well
|
8
|
+
will tell each step before performing it.
|
28
9
|
LONGDESC
|
29
10
|
|
30
11
|
def security_update(step = 'prepare')
|
12
|
+
master = Util.git_default_branch
|
13
|
+
|
31
14
|
case step
|
32
15
|
when 'prepare'
|
33
16
|
Interaction.announce 'Preparing for security update'
|
@@ -56,11 +39,11 @@ def security_update(step = 'prepare')
|
|
56
39
|
Interaction.note 'Working directory clean.'
|
57
40
|
Interaction.prompt('Have you successfully run all tests?', 'n', /y|yes/) || Interaction.fail('Please run tests first.')
|
58
41
|
|
59
|
-
Interaction.note
|
42
|
+
Interaction.note "About to: push production, checkout & pull #{master}, merge production, push #{master}."
|
60
43
|
Interaction.prompt('Continue?', 'n', /y|yes/) || Interaction.fail('Cancelled.')
|
61
44
|
|
62
45
|
Util.run!('git push', show_cmd: true)
|
63
|
-
Util.run!(
|
46
|
+
Util.run!("git checkout #{master}", show_cmd: true)
|
64
47
|
Util.run!('git pull', show_cmd: true)
|
65
48
|
Util.run!('git merge production', show_cmd: true)
|
66
49
|
Util.run!('git push', show_cmd: true)
|
@@ -106,5 +89,7 @@ def security_update(step = 'prepare')
|
|
106
89
|
puts
|
107
90
|
Interaction.note 'Now send an email to customer and project lead, informing them about the update.'
|
108
91
|
Interaction.note 'Do not forget to make a joblog on a security budget, if available.'
|
92
|
+
else
|
93
|
+
Interaction.fail "Unsupported step #{step.inspect}"
|
109
94
|
end
|
110
95
|
end
|
data/lib/geordi/gitlinear.rb
CHANGED
@@ -31,11 +31,12 @@ module Geordi
|
|
31
31
|
matching_local_branch = local_branches.find { |branch_name| branch_name == issue['branchName'] }
|
32
32
|
matching_local_branch ||= local_branches.find { |branch_name| branch_name.include? issue['identifier'].to_s }
|
33
33
|
|
34
|
-
if matching_local_branch
|
35
|
-
Util.run! ['git', 'checkout', 'master'] if from_master
|
36
|
-
Util.run! ['git', 'checkout', '-b', issue['branchName']]
|
37
|
-
else
|
34
|
+
if matching_local_branch
|
38
35
|
Util.run! ['git', 'checkout', matching_local_branch]
|
36
|
+
else
|
37
|
+
default_branch = Util.git_default_branch
|
38
|
+
Util.run! ['git', 'checkout', default_branch] if from_master
|
39
|
+
Util.run! ['git', 'checkout', '-b', issue['branchName']]
|
39
40
|
end
|
40
41
|
end
|
41
42
|
|
@@ -51,11 +52,7 @@ module Geordi
|
|
51
52
|
`git branch --format="%(refname:short)"`
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
Interaction.fail 'Could not determine local Git branches.'
|
56
|
-
end
|
57
|
-
|
58
|
-
branch_list_string.split("\n")
|
55
|
+
branch_list_string.strip.split("\n")
|
59
56
|
end
|
60
57
|
end
|
61
58
|
|
@@ -64,42 +61,36 @@ module Geordi
|
|
64
61
|
return dummy_issue_for_testing
|
65
62
|
end
|
66
63
|
|
67
|
-
loading_message = 'Connecting to Linear ...'
|
68
|
-
print(loading_message)
|
69
64
|
issues = fetch_linear_issues
|
70
|
-
reset_loading_message = "\r#{' ' * (loading_message.length + issues.length)}\r"
|
71
|
-
|
72
65
|
if issues.empty?
|
73
|
-
print reset_loading_message
|
74
66
|
Geordi::Interaction.fail('No issues to offer.')
|
75
67
|
end
|
68
|
+
issues.sort_by! { |i| -i.dig('state', 'position') }
|
76
69
|
|
77
70
|
highline.choose do |menu|
|
78
|
-
|
71
|
+
max_label_length = 60
|
72
|
+
menu.header = 'Choose a started issue (ordered by state)'
|
79
73
|
|
80
74
|
issues.each do |issue|
|
75
|
+
id = issue['identifier']
|
76
|
+
title = issue['title']
|
81
77
|
state = issue['state']['name']
|
82
|
-
|
83
|
-
assignee = issue['assignee']['name']
|
84
|
-
assignee_is_me = issue['assignee']['isMe']
|
85
|
-
else
|
86
|
-
assignee = "unassigned"
|
87
|
-
assignee_is_me = false
|
88
|
-
end
|
89
|
-
|
90
|
-
state += HighLine::BOLD if assignee_is_me
|
78
|
+
assignee = issue.dig('assignee', 'displayName') || 'unassigned'
|
91
79
|
|
92
|
-
label = "
|
93
|
-
label =
|
80
|
+
label = "[#{id}] #{title}"
|
81
|
+
label = "#{label[0..(max_label_length - 5)]} ..." if label.length > max_label_length
|
82
|
+
label = HighLine::BLUE + HighLine::BOLD + label + HighLine::RESET if issue.dig('assignee', 'isMe')
|
83
|
+
label = "#{label} (#{assignee} / #{state})"
|
94
84
|
|
95
85
|
menu.choice(label) { return issue }
|
96
86
|
end
|
97
87
|
|
98
88
|
menu.hidden('') { Interaction.fail('No issue selected.') }
|
99
|
-
print reset_loading_message # Once menu is build
|
100
89
|
end
|
101
90
|
|
102
|
-
|
91
|
+
# Selecting an issue will return that issue. If we ever get here, return
|
92
|
+
# nothing
|
93
|
+
nil
|
103
94
|
end
|
104
95
|
|
105
96
|
def dummy_issue_for_testing
|
@@ -143,11 +134,12 @@ module Geordi
|
|
143
134
|
url
|
144
135
|
branchName
|
145
136
|
assignee {
|
146
|
-
|
137
|
+
displayName
|
147
138
|
isMe
|
148
139
|
}
|
149
140
|
state {
|
150
|
-
|
141
|
+
name
|
142
|
+
position
|
151
143
|
}
|
152
144
|
}
|
153
145
|
}
|
@@ -159,11 +151,14 @@ module Geordi
|
|
159
151
|
|
160
152
|
def query_api(attributes, variables)
|
161
153
|
uri = URI(API_ENDPOINT)
|
154
|
+
loading_message = "Connecting to #{uri.host} ... "
|
155
|
+
clear_loading_message = "\r#{' ' * loading_message.length}\r"
|
162
156
|
|
157
|
+
print(loading_message)
|
163
158
|
https = Net::HTTP.new(uri.host, uri.port)
|
164
159
|
https.use_ssl = true
|
165
160
|
|
166
|
-
query =
|
161
|
+
query = { query: attributes.split.join(' '), variables: variables }.to_json
|
167
162
|
|
168
163
|
request = Net::HTTP::Post.new(uri.path)
|
169
164
|
request.body = query
|
@@ -172,17 +167,22 @@ module Geordi
|
|
172
167
|
request['Authorization'] = settings.linear_api_key
|
173
168
|
|
174
169
|
response = https.request(request)
|
170
|
+
parsed_response = JSON.parse(response.body)
|
175
171
|
|
176
|
-
parsed_response = JSON.parse(response.body)[0]
|
177
172
|
if parsed_response.key?('errors')
|
178
|
-
|
173
|
+
errors = parsed_response['errors'].map do |error|
|
174
|
+
msg = error.delete('message')
|
175
|
+
"#{msg} #{error.inspect}"
|
176
|
+
end
|
177
|
+
Interaction.fail <<~MSG.strip
|
178
|
+
API request failed:
|
179
|
+
#{errors.join("\n")}
|
180
|
+
MSG
|
179
181
|
else
|
180
|
-
|
182
|
+
print clear_loading_message
|
183
|
+
parsed_response.dig('data')
|
181
184
|
end
|
182
185
|
end
|
183
186
|
|
184
|
-
def bold(string)
|
185
|
-
HighLine::BOLD + string + HighLine::RESET
|
186
|
-
end
|
187
187
|
end
|
188
188
|
end
|
data/lib/geordi/interaction.rb
CHANGED
data/lib/geordi/settings.rb
CHANGED
@@ -62,8 +62,8 @@ module Geordi
|
|
62
62
|
|
63
63
|
if team_ids.empty?
|
64
64
|
Geordi::Interaction.warn 'No team id found.'
|
65
|
-
|
66
|
-
|
65
|
+
puts 'Please open a team in Linear, open the command menu with CTRL + K and choose'
|
66
|
+
puts "\"Copy model UUID\". Store that team id in #{LOCAL_SETTINGS_FILE_NAME}:"
|
67
67
|
puts 'linear_team_ids: abc-123-123-abc, def-456-456-def'
|
68
68
|
exit 1
|
69
69
|
end
|
@@ -110,7 +110,12 @@ module Geordi
|
|
110
110
|
def save_global_settings
|
111
111
|
global_path = GLOBAL_SETTINGS_FILE_NAME
|
112
112
|
global_directory = File.dirname(global_path)
|
113
|
-
|
113
|
+
|
114
|
+
unless File.directory?(global_directory)
|
115
|
+
require 'fileutils'
|
116
|
+
FileUtils.mkdir_p(global_directory)
|
117
|
+
end
|
118
|
+
|
114
119
|
File.open(global_path, 'w') do |file|
|
115
120
|
file.write @global_settings.to_yaml
|
116
121
|
end
|
data/lib/geordi/util.rb
CHANGED
@@ -116,7 +116,7 @@ module Geordi
|
|
116
116
|
|
117
117
|
def current_branch
|
118
118
|
if testing?
|
119
|
-
|
119
|
+
git_default_branch
|
120
120
|
else
|
121
121
|
`git rev-parse --abbrev-ref HEAD`.strip
|
122
122
|
end
|
@@ -217,6 +217,18 @@ module Geordi
|
|
217
217
|
def rspec_path?(path)
|
218
218
|
%r{(^|\/)spec|_spec\.rb($|:)}.match?(path)
|
219
219
|
end
|
220
|
+
|
221
|
+
def git_default_branch
|
222
|
+
default_branch = if testing?
|
223
|
+
ENV['GEORDI_TESTING_DEFAULT_BRANCH']
|
224
|
+
else
|
225
|
+
head_symref = `git ls-remote --symref origin HEAD`
|
226
|
+
head_symref[%r{\Aref: refs/heads/(\S+)\sHEAD}, 1]
|
227
|
+
end
|
228
|
+
|
229
|
+
default_branch || 'master'
|
230
|
+
end
|
231
|
+
|
220
232
|
end
|
221
233
|
end
|
222
234
|
end
|
data/lib/geordi/version.rb
CHANGED
@@ -0,0 +1,125 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
6
|
+
xmlns:cc="http://creativecommons.org/ns#"
|
7
|
+
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
8
|
+
xmlns:svg="http://www.w3.org/2000/svg"
|
9
|
+
xmlns="http://www.w3.org/2000/svg"
|
10
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
11
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
width="35.7663mm"
|
14
|
+
height="14.056225mm"
|
15
|
+
viewBox="0 0 35.766299 14.056225"
|
16
|
+
version="1.1"
|
17
|
+
id="svg838"
|
18
|
+
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
|
19
|
+
sodipodi:docname="logo.dark.shapes.svg"
|
20
|
+
inkscape:export-filename="/home/henning/Projects/capybara-lockstep/media/capybara-lockstep.dark.png"
|
21
|
+
inkscape:export-xdpi="196"
|
22
|
+
inkscape:export-ydpi="196">
|
23
|
+
<defs
|
24
|
+
id="defs832">
|
25
|
+
<linearGradient
|
26
|
+
inkscape:collect="always"
|
27
|
+
id="linearGradient1406">
|
28
|
+
<stop
|
29
|
+
style="stop-color:#ff0844;stop-opacity:1"
|
30
|
+
offset="0"
|
31
|
+
id="stop1402" />
|
32
|
+
<stop
|
33
|
+
style="stop-color:#ffb199;stop-opacity:1"
|
34
|
+
offset="1"
|
35
|
+
id="stop1404" />
|
36
|
+
</linearGradient>
|
37
|
+
<linearGradient
|
38
|
+
inkscape:collect="always"
|
39
|
+
xlink:href="#linearGradient1406"
|
40
|
+
id="linearGradient1408"
|
41
|
+
x1="22.054907"
|
42
|
+
y1="91.071762"
|
43
|
+
x2="88.956696"
|
44
|
+
y2="91.071762"
|
45
|
+
gradientUnits="userSpaceOnUse"
|
46
|
+
gradientTransform="matrix(0.53371623,0,0,0.08820435,-11.771062,57.908781)" />
|
47
|
+
</defs>
|
48
|
+
<sodipodi:namedview
|
49
|
+
id="base"
|
50
|
+
pagecolor="#ffffff"
|
51
|
+
bordercolor="#666666"
|
52
|
+
borderopacity="1.0"
|
53
|
+
inkscape:pageopacity="0.0"
|
54
|
+
inkscape:pageshadow="2"
|
55
|
+
inkscape:zoom="3.959798"
|
56
|
+
inkscape:cx="107.13075"
|
57
|
+
inkscape:cy="16.774239"
|
58
|
+
inkscape:document-units="mm"
|
59
|
+
inkscape:current-layer="layer1"
|
60
|
+
showgrid="false"
|
61
|
+
fit-margin-top="0"
|
62
|
+
fit-margin-left="0"
|
63
|
+
fit-margin-right="0"
|
64
|
+
fit-margin-bottom="0"
|
65
|
+
inkscape:window-width="2560"
|
66
|
+
inkscape:window-height="1391"
|
67
|
+
inkscape:window-x="1920"
|
68
|
+
inkscape:window-y="0"
|
69
|
+
inkscape:window-maximized="1"
|
70
|
+
inkscape:pagecheckerboard="true" />
|
71
|
+
<metadata
|
72
|
+
id="metadata835">
|
73
|
+
<rdf:RDF>
|
74
|
+
<cc:Work
|
75
|
+
rdf:about="">
|
76
|
+
<dc:format>image/svg+xml</dc:format>
|
77
|
+
<dc:type
|
78
|
+
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
79
|
+
<dc:title></dc:title>
|
80
|
+
</cc:Work>
|
81
|
+
</rdf:RDF>
|
82
|
+
</metadata>
|
83
|
+
<g
|
84
|
+
inkscape:label="Layer 1"
|
85
|
+
inkscape:groupmode="layer"
|
86
|
+
id="layer1"
|
87
|
+
transform="translate(0.05820833,-52.518951)">
|
88
|
+
<g
|
89
|
+
aria-label="GEORDI"
|
90
|
+
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.58333302px;line-height:1.25;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26458332"
|
91
|
+
id="text1385">
|
92
|
+
<path
|
93
|
+
d="m 3.4766249,55.725701 h 3.5612916 v 0.4445 q 0,0.751417 -0.254,1.402292 -0.2487084,0.650875 -0.714375,1.143 -0.4656667,0.492125 -1.11125,0.767291 -0.6455833,0.275167 -1.4287499,0.275167 -0.809625,0 -1.4710833,-0.275167 -0.6561667,-0.280458 -1.13241666,-0.777875 -0.47624999,-0.497416 -0.73024998,-1.153583 -0.25399999,-0.661458 -0.25399999,-1.418167 0,-0.751416 0.25399999,-1.407583 0.25399999,-0.661458 0.73024998,-1.153583 0.47624996,-0.497417 1.13241666,-0.772584 0.6614583,-0.280458 1.4710833,-0.280458 0.6614583,0 1.1641666,0.142875 0.508,0.142875 0.873125,0.381 0.365125,0.238125 0.6191249,0.523875 0.254,0.280458 0.4233334,0.550333 L 5.1064582,54.826118 Q 4.8894999,54.492743 4.5137915,54.244034 4.1433749,53.995326 3.5295416,53.995326 q -0.428625,0 -0.7884584,0.169333 Q 2.3865416,54.333993 2.1272499,54.630326 1.8679583,54.921368 1.7250833,55.312951 1.5875,55.699243 1.5875,56.133159 q 0,0.439209 0.1375833,0.8255 0.142875,0.386292 0.4021666,0.682625 0.2592917,0.296334 0.6138333,0.465667 0.3598334,0.164042 0.7884584,0.164042 0.3757083,0 0.6826249,-0.09525 0.3069167,-0.09525 0.5291667,-0.275167 0.2275416,-0.179917 0.3545416,-0.423333 0.1322917,-0.248709 0.15875,-0.545042 H 3.4766249 Z"
|
94
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
95
|
+
id="path822" />
|
96
|
+
<path
|
97
|
+
d="m 7.9427778,52.645951 h 4.4608752 v 1.386417 H 9.5196944 v 1.423458 h 2.8574996 v 1.344083 H 9.5196944 v 1.444625 h 2.8839586 v 1.386417 H 7.9427778 Z"
|
98
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
99
|
+
id="path824" />
|
100
|
+
<path
|
101
|
+
d="m 15.023009,56.133159 q 0,0.597959 0.243416,1.084792 0.248709,0.481542 0.682625,0.767292 0.439209,0.28575 1.016,0.28575 0.576792,0 1.010709,-0.28575 0.439208,-0.28575 0.682625,-0.767292 0.248708,-0.486833 0.248708,-1.084792 0,-0.597958 -0.248708,-1.0795 -0.243417,-0.481541 -0.682625,-0.767291 -0.433917,-0.291042 -1.010709,-0.291042 -0.576791,0 -1.016,0.291042 -0.433916,0.28575 -0.682625,0.767291 -0.243416,0.481542 -0.243416,1.0795 z m -1.645709,0 q 0,-0.762 0.269875,-1.418166 0.269875,-0.661459 0.756709,-1.153584 0.486833,-0.492125 1.143,-0.767291 0.656166,-0.275167 1.418166,-0.275167 0.772584,0 1.423459,0.275167 0.656166,0.275166 1.137708,0.767291 0.486833,0.492125 0.751417,1.153584 0.269875,0.656166 0.269875,1.418166 0,0.767292 -0.259292,1.42875 -0.259292,0.656167 -0.740833,1.153584 -0.481542,0.492125 -1.137709,0.767291 -0.656166,0.275167 -1.444625,0.275167 -0.804333,0 -1.465791,-0.275167 -0.656167,-0.275166 -1.132417,-0.767291 -0.47625,-0.497417 -0.735542,-1.153584 -0.254,-0.661458 -0.254,-1.42875 z"
|
102
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
103
|
+
id="path826" />
|
104
|
+
<path
|
105
|
+
d="m 21.42062,52.645951 h 2.846916 q 0.608542,0 1.084792,0.254 0.47625,0.254 0.751417,0.735542 0.280458,0.47625 0.280458,1.137708 0,0.661458 -0.238125,1.084792 -0.232833,0.418041 -0.560917,0.629708 -0.328083,0.206375 -0.608541,0.248708 l 1.698625,2.894542 h -1.778 l -1.513417,-2.772833 h -0.381 v 2.772833 H 21.42062 Z m 1.582208,3.116792 h 0.6985 q 0.423333,0 0.740833,-0.206375 0.3175,-0.206375 0.3175,-0.73025 0,-0.523875 -0.312208,-0.724959 -0.312208,-0.206375 -0.735542,-0.206375 h -0.709083 z"
|
106
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
107
|
+
id="path828" />
|
108
|
+
<path
|
109
|
+
d="m 27.728279,52.645951 h 2.100792 q 1.116542,0 1.846792,0.449792 0.735541,0.4445 1.100666,1.232958 0.365125,0.788458 0.365125,1.804458 0,1.021292 -0.365125,1.80975 -0.365125,0.788459 -1.100666,1.23825 -0.73025,0.449792 -1.846792,0.449792 h -2.100792 z m 1.576917,1.402292 v 4.180416 h 0.381 q 0.597958,0 0.989542,-0.269875 0.391583,-0.275166 0.587375,-0.746125 0.201083,-0.47625 0.201083,-1.068916 0,-0.597959 -0.195792,-1.068917 -0.1905,-0.47625 -0.587375,-0.751417 -0.396875,-0.275166 -0.994833,-0.275166 z"
|
110
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
111
|
+
id="path830" />
|
112
|
+
<path
|
113
|
+
d="m 34.125883,52.645951 h 1.582208 v 6.985 h -1.582208 z"
|
114
|
+
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-family:'League Spartan';-inkscape-font-specification:'League Spartan';fill:#ffffff;fill-opacity:1;stroke-width:0.26458332"
|
115
|
+
id="path832" />
|
116
|
+
</g>
|
117
|
+
<rect
|
118
|
+
style="fill:url(#linearGradient1408);fill-opacity:1;stroke:none;stroke-width:0.02169702;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
119
|
+
id="rect1387"
|
120
|
+
width="35.70657"
|
121
|
+
height="1.2668874"
|
122
|
+
x="-3.5435547e-15"
|
123
|
+
y="65.308289" />
|
124
|
+
</g>
|
125
|
+
</svg>
|