git_dossier 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 93c3b2950879b0f17bdaa0e030c28d95aaba6f10
4
+ data.tar.gz: 1baffee823bacf6ebccd39add70f01706f695136
5
+ SHA512:
6
+ metadata.gz: b77eb690b32161fe6da4119e000e305f0c1fac629096f1647610856c140a3c59b13279738e3e3003b2225847a0a6c252067f5098288ea63a6376611c6dd71601
7
+ data.tar.gz: ed654826d990b1c743ab33a823d294842f472d433cb277a3150313c6bce6cf23530abe0d881419ce531ed81c0aad45e8269587ab7b999d3c486cf9e4aa3a0643
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.gem
2
+ dossier/
3
+ .sass-cache/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sass'
4
+ gem 'cssminify'
data/Gemfile.lock ADDED
@@ -0,0 +1,28 @@
1
+ GEM
2
+ remote: https://rubygems.org/
3
+ specs:
4
+ activesupport (4.2.5)
5
+ i18n (~> 0.7)
6
+ json (~> 1.7, >= 1.7.7)
7
+ minitest (~> 5.1)
8
+ thread_safe (~> 0.3, >= 0.3.4)
9
+ tzinfo (~> 1.1)
10
+ cssminify (1.0.2)
11
+ i18n (0.7.0)
12
+ json (1.8.3)
13
+ minitest (5.8.4)
14
+ sass (3.4.21)
15
+ thread_safe (0.3.5)
16
+ tzinfo (1.2.2)
17
+ thread_safe (~> 0.1)
18
+
19
+ PLATFORMS
20
+ ruby
21
+
22
+ DEPENDENCIES
23
+ activesupport
24
+ cssminify
25
+ sass
26
+
27
+ BUNDLED WITH
28
+ 1.10.6
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Ivan Božić
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # GitDossier
2
+
3
+ Git Dossier is a tool to generate static websites that visualize your git repository in a beautiful way.
4
+
5
+ ### Note: This is a _really_ early version and there is still a lot more work to generate really meaningful and beautiful data.
6
+
7
+ ## Installation
8
+
9
+ $ gem install git_dossier
10
+
11
+ ## Usage
12
+
13
+ Once you are positioned in a folder that has the Git repository that you want to generate a _dossier_ for, just type in:
14
+
15
+ $ git_dossier generate <branch>
16
+
17
+ If you leave out the <branch> option, the data will be pulled from the *master* branch by default.
@@ -0,0 +1,67 @@
1
+ setInterval(function () {
2
+ console.log('Init.');
3
+ }, 2000);
4
+
5
+
6
+ var colors = new Array(
7
+ [62,35,255],
8
+ [60,255,60],
9
+ [255,35,98],
10
+ [45,175,230],
11
+ [255,0,255],
12
+ [255,128,0]
13
+ );
14
+
15
+ var step = 0;
16
+ //color table indices for:
17
+ // current color left
18
+ // next color left
19
+ // current color right
20
+ // next color right
21
+ var colorIndices = [0,1,2,3];
22
+
23
+ //transition speed
24
+ var gradientSpeed = 0.002;
25
+
26
+ function updateGradient() {
27
+ console.log('updateGradient');
28
+
29
+ if ($ === undefined) {
30
+ return;
31
+ }
32
+
33
+ var c0_0 = colors[colorIndices[0]];
34
+ var c0_1 = colors[colorIndices[1]];
35
+ var c1_0 = colors[colorIndices[2]];
36
+ var c1_1 = colors[colorIndices[3]];
37
+
38
+ var istep = 1 - step;
39
+ var r1 = Math.round(istep * c0_0[0] + step * c0_1[0]);
40
+ var g1 = Math.round(istep * c0_0[1] + step * c0_1[1]);
41
+ var b1 = Math.round(istep * c0_0[2] + step * c0_1[2]);
42
+ var color1 = "rgb("+r1+","+g1+","+b1+")";
43
+
44
+ var r2 = Math.round(istep * c1_0[0] + step * c1_1[0]);
45
+ var g2 = Math.round(istep * c1_0[1] + step * c1_1[1]);
46
+ var b2 = Math.round(istep * c1_0[2] + step * c1_1[2]);
47
+ var color2 = "rgb("+r2+","+g2+","+b2+")";
48
+
49
+ $('.js-gradient')
50
+ .css({background: "-webkit-gradient(linear, left top, right top, from("+color1+"), to("+color2+"))"})
51
+ .css({background: "-moz-linear-gradient(left, "+color1+" 0%, "+color2+" 100%)"});
52
+
53
+ step += gradientSpeed;
54
+
55
+ if (step >= 1) {
56
+ step %= 1;
57
+ colorIndices[0] = colorIndices[1];
58
+ colorIndices[2] = colorIndices[3];
59
+
60
+ //pick two new target color indices
61
+ //do not pick the same as the current one
62
+ colorIndices[1] = ( colorIndices[1] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
63
+ colorIndices[3] = ( colorIndices[3] + Math.floor( 1 + Math.random() * (colors.length - 1))) % colors.length;
64
+ }
65
+ }
66
+
67
+ setInterval(updateGradient, 50);
@@ -0,0 +1,215 @@
1
+ @import "normalize";
2
+
3
+ @mixin clearfix {
4
+ *zoom: 1;
5
+
6
+ &:before,
7
+ &:after {
8
+ content: " ";
9
+ display: table;
10
+ }
11
+
12
+ &:after {
13
+ clear: both;
14
+ }
15
+
16
+ }
17
+
18
+ html {
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ *, *:before, *:after {
23
+ box-sizing: inherit;
24
+ }
25
+
26
+ body {
27
+ background: #fcfcfc;
28
+ font-family: 'Helvetica Neue', 'Helvetica', 'Arial', sans-serif;
29
+ font-size: 16px;
30
+ }
31
+
32
+ h1, h2, h3, h4, h5, h6 {
33
+ margin: 0;
34
+ padding: 0;
35
+ }
36
+
37
+ p {
38
+ margin: 0;
39
+ padding: 0;
40
+ }
41
+
42
+ .hero {
43
+ padding: 100px 0;
44
+ background: deeppink;
45
+ text-align: center;
46
+
47
+ h1 {
48
+ margin: 0 0 10px 0;
49
+ color: #fff;
50
+ font-size: 48px;
51
+ }
52
+
53
+ p {
54
+ color: rgba(255,255,255,0.75);
55
+ font-size: 18px;
56
+ }
57
+
58
+ }
59
+
60
+ .authors {
61
+ padding: 80px;
62
+ text-align: center;
63
+ }
64
+
65
+ .authors__badge {
66
+ @include clearfix;
67
+
68
+ display: inline-block;
69
+ border-radius: 72px;
70
+ margin: 10px;
71
+ padding: 8px;
72
+ background: #e8e8e8;
73
+ }
74
+
75
+ .authors__badge__image {
76
+ float: left;
77
+ width: 40px;
78
+ height: 40px;
79
+ border-radius: 100%;
80
+ }
81
+
82
+ .authors__badge__info {
83
+ float: left;
84
+ text-align: left;
85
+ margin: 0px 10px 0 10px;
86
+ }
87
+
88
+ .authors__badge__name {
89
+ margin-bottom: 4px;
90
+ color: #111;
91
+ font-size: 16px;
92
+ font-weight: bold;
93
+ }
94
+
95
+ .authors__badge__email {
96
+ color: #777;
97
+ font-size: 13px;
98
+ }
99
+
100
+ .authors__badge__count {
101
+ float: left;
102
+ width: 40px;
103
+ height: 40px;
104
+ border-radius: 100%;
105
+ background: green;
106
+ text-align: center;
107
+
108
+ &.authors__badge__count--0 {
109
+ background: #F7674B;
110
+ }
111
+
112
+ &.authors__badge__count--1 {
113
+ background: #F7674B;
114
+ }
115
+
116
+ &.authors__badge__count--2 {
117
+ background: #FC8945;
118
+ }
119
+
120
+ &.authors__badge__count--3 {
121
+ background: #F6AB44;
122
+ }
123
+
124
+ &.authors__badge__count--4 {
125
+ background: #F7CA3A;
126
+ }
127
+
128
+ &.authors__badge__count--5 {
129
+ background: #F9DC3D;
130
+ }
131
+
132
+ &.authors__badge__count--6 {
133
+ background: #D1EF5F;
134
+ }
135
+
136
+ &.authors__badge__count--7 {
137
+ background: #A3E667;
138
+ }
139
+
140
+ &.authors__badge__count--8 {
141
+ background: #78E869;
142
+ }
143
+
144
+ &.authors__badge__count--9 {
145
+ background: #5ADE69;
146
+ }
147
+
148
+ &.authors__badge__count--10 {
149
+ background: #2BCA43;
150
+ }
151
+
152
+ p {
153
+ color: #fff;
154
+ font-weight: bold;
155
+ line-height: 38px;
156
+ }
157
+
158
+ }
159
+
160
+ .commits {
161
+ width: 1200px;
162
+ margin: 0 auto;
163
+
164
+ table {
165
+ width: 100%;
166
+ }
167
+
168
+ tr {
169
+ border-bottom: 1px solid #f0f0f0;
170
+
171
+ &:nth-child(even) {
172
+ background: #f8f8f8;
173
+ }
174
+
175
+ }
176
+
177
+ td {
178
+ padding: 10px;
179
+
180
+ p {
181
+ margin-bottom: 4px;
182
+ color: #111;
183
+ font-size: 15px;
184
+ }
185
+
186
+ small {
187
+ color: #777;
188
+ font-family: monospace;
189
+ font-size: 13px;
190
+ }
191
+
192
+ }
193
+
194
+ }
195
+
196
+ footer {
197
+ margin-top: 80px;
198
+ padding: 30px 0;
199
+ background: #2C2935;
200
+ text-align: center;
201
+
202
+ p {
203
+ color: rgba(255,255,255,0.75);
204
+ font-size: 14px;
205
+
206
+ a {
207
+ border-bottom: 2px solid crimson;
208
+ color: crimson;
209
+ font-weight: bold;
210
+ text-decoration: none;
211
+ }
212
+
213
+ }
214
+
215
+ }
@@ -0,0 +1,427 @@
1
+ /*! normalize.css v3.0.2 | MIT License | git.io/normalize */
2
+
3
+ /**
4
+ * 1. Set default font family to sans-serif.
5
+ * 2. Prevent iOS text size adjust after orientation change, without disabling
6
+ * user zoom.
7
+ */
8
+
9
+ html {
10
+ font-family: sans-serif; /* 1 */
11
+ -ms-text-size-adjust: 100%; /* 2 */
12
+ -webkit-text-size-adjust: 100%; /* 2 */
13
+ }
14
+
15
+ /**
16
+ * Remove default margin.
17
+ */
18
+
19
+ body {
20
+ margin: 0;
21
+ }
22
+
23
+ /* HTML5 display definitions
24
+ ========================================================================== */
25
+
26
+ /**
27
+ * Correct `block` display not defined for any HTML5 element in IE 8/9.
28
+ * Correct `block` display not defined for `details` or `summary` in IE 10/11
29
+ * and Firefox.
30
+ * Correct `block` display not defined for `main` in IE 11.
31
+ */
32
+
33
+ article,
34
+ aside,
35
+ details,
36
+ figcaption,
37
+ figure,
38
+ footer,
39
+ header,
40
+ hgroup,
41
+ main,
42
+ menu,
43
+ nav,
44
+ section,
45
+ summary {
46
+ display: block;
47
+ }
48
+
49
+ /**
50
+ * 1. Correct `inline-block` display not defined in IE 8/9.
51
+ * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
52
+ */
53
+
54
+ audio,
55
+ canvas,
56
+ progress,
57
+ video {
58
+ display: inline-block; /* 1 */
59
+ vertical-align: baseline; /* 2 */
60
+ }
61
+
62
+ /**
63
+ * Prevent modern browsers from displaying `audio` without controls.
64
+ * Remove excess height in iOS 5 devices.
65
+ */
66
+
67
+ audio:not([controls]) {
68
+ display: none;
69
+ height: 0;
70
+ }
71
+
72
+ /**
73
+ * Address `[hidden]` styling not present in IE 8/9/10.
74
+ * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
75
+ */
76
+
77
+ [hidden],
78
+ template {
79
+ display: none;
80
+ }
81
+
82
+ /* Links
83
+ ========================================================================== */
84
+
85
+ /**
86
+ * Remove the gray background color from active links in IE 10.
87
+ */
88
+
89
+ a {
90
+ background-color: transparent;
91
+ }
92
+
93
+ /**
94
+ * Improve readability when focused and also mouse hovered in all browsers.
95
+ */
96
+
97
+ a:active,
98
+ a:hover {
99
+ outline: 0;
100
+ }
101
+
102
+ /* Text-level semantics
103
+ ========================================================================== */
104
+
105
+ /**
106
+ * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
107
+ */
108
+
109
+ abbr[title] {
110
+ border-bottom: 1px dotted;
111
+ }
112
+
113
+ /**
114
+ * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
115
+ */
116
+
117
+ b,
118
+ strong {
119
+ font-weight: bold;
120
+ }
121
+
122
+ /**
123
+ * Address styling not present in Safari and Chrome.
124
+ */
125
+
126
+ dfn {
127
+ font-style: italic;
128
+ }
129
+
130
+ /**
131
+ * Address variable `h1` font-size and margin within `section` and `article`
132
+ * contexts in Firefox 4+, Safari, and Chrome.
133
+ */
134
+
135
+ h1 {
136
+ font-size: 2em;
137
+ margin: 0.67em 0;
138
+ }
139
+
140
+ /**
141
+ * Address styling not present in IE 8/9.
142
+ */
143
+
144
+ mark {
145
+ background: #ff0;
146
+ color: #000;
147
+ }
148
+
149
+ /**
150
+ * Address inconsistent and variable font size in all browsers.
151
+ */
152
+
153
+ small {
154
+ font-size: 80%;
155
+ }
156
+
157
+ /**
158
+ * Prevent `sub` and `sup` affecting `line-height` in all browsers.
159
+ */
160
+
161
+ sub,
162
+ sup {
163
+ font-size: 75%;
164
+ line-height: 0;
165
+ position: relative;
166
+ vertical-align: baseline;
167
+ }
168
+
169
+ sup {
170
+ top: -0.5em;
171
+ }
172
+
173
+ sub {
174
+ bottom: -0.25em;
175
+ }
176
+
177
+ /* Embedded content
178
+ ========================================================================== */
179
+
180
+ /**
181
+ * Remove border when inside `a` element in IE 8/9/10.
182
+ */
183
+
184
+ img {
185
+ border: 0;
186
+ }
187
+
188
+ /**
189
+ * Correct overflow not hidden in IE 9/10/11.
190
+ */
191
+
192
+ svg:not(:root) {
193
+ overflow: hidden;
194
+ }
195
+
196
+ /* Grouping content
197
+ ========================================================================== */
198
+
199
+ /**
200
+ * Address margin not present in IE 8/9 and Safari.
201
+ */
202
+
203
+ figure {
204
+ margin: 1em 40px;
205
+ }
206
+
207
+ /**
208
+ * Address differences between Firefox and other browsers.
209
+ */
210
+
211
+ hr {
212
+ -moz-box-sizing: content-box;
213
+ box-sizing: content-box;
214
+ height: 0;
215
+ }
216
+
217
+ /**
218
+ * Contain overflow in all browsers.
219
+ */
220
+
221
+ pre {
222
+ overflow: auto;
223
+ }
224
+
225
+ /**
226
+ * Address odd `em`-unit font size rendering in all browsers.
227
+ */
228
+
229
+ code,
230
+ kbd,
231
+ pre,
232
+ samp {
233
+ font-family: monospace, monospace;
234
+ font-size: 1em;
235
+ }
236
+
237
+ /* Forms
238
+ ========================================================================== */
239
+
240
+ /**
241
+ * Known limitation: by default, Chrome and Safari on OS X allow very limited
242
+ * styling of `select`, unless a `border` property is set.
243
+ */
244
+
245
+ /**
246
+ * 1. Correct color not being inherited.
247
+ * Known issue: affects color of disabled elements.
248
+ * 2. Correct font properties not being inherited.
249
+ * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
250
+ */
251
+
252
+ button,
253
+ input,
254
+ optgroup,
255
+ select,
256
+ textarea {
257
+ color: inherit; /* 1 */
258
+ font: inherit; /* 2 */
259
+ margin: 0; /* 3 */
260
+ }
261
+
262
+ /**
263
+ * Address `overflow` set to `hidden` in IE 8/9/10/11.
264
+ */
265
+
266
+ button {
267
+ overflow: visible;
268
+ }
269
+
270
+ /**
271
+ * Address inconsistent `text-transform` inheritance for `button` and `select`.
272
+ * All other form control elements do not inherit `text-transform` values.
273
+ * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
274
+ * Correct `select` style inheritance in Firefox.
275
+ */
276
+
277
+ button,
278
+ select {
279
+ text-transform: none;
280
+ }
281
+
282
+ /**
283
+ * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
284
+ * and `video` controls.
285
+ * 2. Correct inability to style clickable `input` types in iOS.
286
+ * 3. Improve usability and consistency of cursor style between image-type
287
+ * `input` and others.
288
+ */
289
+
290
+ button,
291
+ html input[type="button"], /* 1 */
292
+ input[type="reset"],
293
+ input[type="submit"] {
294
+ -webkit-appearance: button; /* 2 */
295
+ cursor: pointer; /* 3 */
296
+ }
297
+
298
+ /**
299
+ * Re-set default cursor for disabled elements.
300
+ */
301
+
302
+ button[disabled],
303
+ html input[disabled] {
304
+ cursor: default;
305
+ }
306
+
307
+ /**
308
+ * Remove inner padding and border in Firefox 4+.
309
+ */
310
+
311
+ button::-moz-focus-inner,
312
+ input::-moz-focus-inner {
313
+ border: 0;
314
+ padding: 0;
315
+ }
316
+
317
+ /**
318
+ * Address Firefox 4+ setting `line-height` on `input` using `!important` in
319
+ * the UA stylesheet.
320
+ */
321
+
322
+ input {
323
+ line-height: normal;
324
+ }
325
+
326
+ /**
327
+ * It's recommended that you don't attempt to style these elements.
328
+ * Firefox's implementation doesn't respect box-sizing, padding, or width.
329
+ *
330
+ * 1. Address box sizing set to `content-box` in IE 8/9/10.
331
+ * 2. Remove excess padding in IE 8/9/10.
332
+ */
333
+
334
+ input[type="checkbox"],
335
+ input[type="radio"] {
336
+ box-sizing: border-box; /* 1 */
337
+ padding: 0; /* 2 */
338
+ }
339
+
340
+ /**
341
+ * Fix the cursor style for Chrome's increment/decrement buttons. For certain
342
+ * `font-size` values of the `input`, it causes the cursor style of the
343
+ * decrement button to change from `default` to `text`.
344
+ */
345
+
346
+ input[type="number"]::-webkit-inner-spin-button,
347
+ input[type="number"]::-webkit-outer-spin-button {
348
+ height: auto;
349
+ }
350
+
351
+ /**
352
+ * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
353
+ * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
354
+ * (include `-moz` to future-proof).
355
+ */
356
+
357
+ input[type="search"] {
358
+ -webkit-appearance: textfield; /* 1 */
359
+ -moz-box-sizing: content-box;
360
+ -webkit-box-sizing: content-box; /* 2 */
361
+ box-sizing: content-box;
362
+ }
363
+
364
+ /**
365
+ * Remove inner padding and search cancel button in Safari and Chrome on OS X.
366
+ * Safari (but not Chrome) clips the cancel button when the search input has
367
+ * padding (and `textfield` appearance).
368
+ */
369
+
370
+ input[type="search"]::-webkit-search-cancel-button,
371
+ input[type="search"]::-webkit-search-decoration {
372
+ -webkit-appearance: none;
373
+ }
374
+
375
+ /**
376
+ * Define consistent border, margin, and padding.
377
+ */
378
+
379
+ fieldset {
380
+ border: 1px solid #c0c0c0;
381
+ margin: 0 2px;
382
+ padding: 0.35em 0.625em 0.75em;
383
+ }
384
+
385
+ /**
386
+ * 1. Correct `color` not being inherited in IE 8/9/10/11.
387
+ * 2. Remove padding so people aren't caught out if they zero out fieldsets.
388
+ */
389
+
390
+ legend {
391
+ border: 0; /* 1 */
392
+ padding: 0; /* 2 */
393
+ }
394
+
395
+ /**
396
+ * Remove default vertical scrollbar in IE 8/9/10/11.
397
+ */
398
+
399
+ textarea {
400
+ overflow: auto;
401
+ }
402
+
403
+ /**
404
+ * Don't inherit the `font-weight` (applied by a rule above).
405
+ * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
406
+ */
407
+
408
+ optgroup {
409
+ font-weight: bold;
410
+ }
411
+
412
+ /* Tables
413
+ ========================================================================== */
414
+
415
+ /**
416
+ * Remove most spacing between table cells.
417
+ */
418
+
419
+ table {
420
+ border-collapse: collapse;
421
+ border-spacing: 0;
422
+ }
423
+
424
+ td,
425
+ th {
426
+ padding: 0;
427
+ }
@@ -0,0 +1,54 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Dossier</title>
6
+ <link rel="stylesheet" href="./assets/dossier.min.css">
7
+ </head>
8
+ <body>
9
+ <div class="hero js-gradient">
10
+ <h1><%= @project_name %></h1>
11
+ <p><%= pluralize(@authors.count, 'author', 'authors') %> &bullet; <%= pluralize(@commits.count, 'commit', 'commits') %></p>
12
+ </div>
13
+ <div class="authors">
14
+ <% @authors.each do |author| %>
15
+ <div class="authors__badge">
16
+ <img src="http://www.gravatar.com/avatar/<%= author[:gravatar] %>?d=mm" class="authors__badge__image" />
17
+ <div class="authors__badge__info">
18
+ <p class="authors__badge__name"><%= author[:name] %></p>
19
+ <p class="authors__badge__email"><%= author[:email] %></p>
20
+ </div>
21
+ <div class="authors__badge__count authors__badge__count--<%= author[:percentage_normalized] %>">
22
+ <p><%= author[:number_of_commits] %></p>
23
+ </div>
24
+ </div>
25
+ <% end %>
26
+ </div>
27
+ <div class="commits">
28
+ <table>
29
+ <tbody>
30
+ <% @commits.each do |commit| %>
31
+ <tr>
32
+ <td>
33
+ <p><%= commit[:subject] %></p>
34
+ <small><%= commit[:sha] %></small>
35
+ </td>
36
+ <td nowrap>
37
+ <small><%= commit[:timestamp].strftime('%-m/%d/%Y, %I:%M %p') %></small>
38
+ </td>
39
+ <td nowrap>
40
+ <p><%= commit[:author][:name] %></p>
41
+ <small><%= commit[:author][:email] %></small>
42
+ </td>
43
+ </tr>
44
+ <% end %>
45
+ </tbody>
46
+ </table>
47
+ </div>
48
+ <footer>
49
+ <p>This page is generated using <a href="http://github.com/ivanbozic/git_dossier/" target="_blank">Git Dossier</a>.</p>
50
+ </footer>
51
+ <script src="//code.jquery.com/jquery-1.12.0.min.js"></script>
52
+ <script type="text/javascript" src="./assets/javascripts/gradient.js"></script>
53
+ </body>
54
+ </html>
data/bin/git_dossier ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'git_dossier'
4
+
5
+ if ARGV[0] == nil
6
+ puts "\e[31mYou have to pass in an option. Try 'generate'.\e[0m"
7
+ else
8
+ case ARGV[0]
9
+ when 'generate'
10
+ if ARGV[1] == nil
11
+ GitDossier.generate
12
+ else
13
+ GitDossier.generate(ARGV[1])
14
+ end
15
+ else
16
+ puts "\e[31m'#{ARGV[0]}' is not a valid option.\e[0m"
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'git_dossier/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = 'git_dossier'
8
+ s.version = GitDossier::VERSION
9
+ s.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
10
+ s.executables << "git_dossier"
11
+ s.date = '2016-01-25'
12
+ s.summary = "A beautiful way to visualize your git repository."
13
+ s.description = "Git Dossier is a tool to generate static websites that visualize your git repository in a beautiful way."
14
+ s.authors = ["Ivan Bozic"]
15
+ s.email = 'ivan@arsfutura.co'
16
+ s.homepage = 'http://ivanbozic.com/git-dossier/'
17
+ s.license = 'MIT'
18
+ end
@@ -0,0 +1,105 @@
1
+ require 'date'
2
+ require 'erb'
3
+ require 'digest/md5'
4
+ require 'git_dossier/version'
5
+ require 'sass'
6
+ require 'cssminify'
7
+
8
+ def pluralize(n, singular, plural=nil)
9
+ if n == 1
10
+ "1 #{singular}"
11
+ elsif plural
12
+ "#{n} #{plural}"
13
+ else
14
+ "#{n} #{singular}s"
15
+ end
16
+ end
17
+
18
+ module GitDossier
19
+ def self.generate(branch = "master")
20
+ repo_name = %x[git remote -v | head -n1 | awk '{print $2}' | sed -e 's,.*:\(.*/\)\?,,' -e 's/\.git$//']
21
+
22
+ project_name = repo_name.lines.first.split('/').pop
23
+
24
+ response = %x[git rev-parse --verify --quiet #{branch}]
25
+
26
+ if (response.lines.first =~ /\b([a-f0-9]{40})\b/) == 0
27
+ response = %x[git rev-list --pretty=format:'%H|%ai|%an|%aE|%s' #{branch} | grep -v commit]
28
+
29
+ commits = [ ]
30
+ authors = [ ]
31
+
32
+ response.lines.map do |line|
33
+ sha, timestamp, author_name, author_email, subject = line.split('|').map(&:strip)
34
+
35
+ commits.push({
36
+ sha: sha,
37
+ timestamp: DateTime.parse(timestamp),
38
+ subject: subject.strip,
39
+ author: {
40
+ name: author_name,
41
+ email: author_email
42
+ }
43
+ })
44
+
45
+ if authors.any? {|a| a[:email] == author_email}
46
+ authors.each do |a|
47
+ if a[:email] == author_email
48
+ a[:number_of_commits] = a[:number_of_commits] + 1
49
+ end
50
+ end
51
+ else
52
+ authors.push({
53
+ name: author_name,
54
+ email: author_email,
55
+ gravatar: Digest::MD5.hexdigest(author_email.downcase),
56
+ number_of_commits: 1,
57
+ percentage_of_commits: 0
58
+ })
59
+ end
60
+ end
61
+
62
+ normalization_bound = 0.0
63
+
64
+ authors.each do |a|
65
+ a[:percentage_of_commits] = a[:number_of_commits].to_f / commits.count
66
+
67
+ if a[:percentage_of_commits] > normalization_bound
68
+ normalization_bound = a[:percentage_of_commits]
69
+ end
70
+ end
71
+
72
+ authors.each do |a|
73
+ if a[:percentage_of_commits] == normalization_bound
74
+ a[:percentage_normalized] = 10
75
+ else
76
+ a[:percentage_normalized] = (((a[:percentage_of_commits] / normalization_bound) * 10) % 10).to_i
77
+ end
78
+ end
79
+
80
+ Dir.mkdir('dossier') unless Dir.exist?('dossier')
81
+ Dir.mkdir('dossier/assets') unless Dir.exist?('dossier/assets')
82
+
83
+ File.open("dossier/index.html", 'w') { |f|
84
+ @project_name = project_name
85
+ @commits = commits
86
+ @authors = authors.sort_by { |a| a[:number_of_commits] }.reverse
87
+
88
+ erb = ERB.new(File.open("#{__dir__}/../app/views/index.html.erb").read)
89
+
90
+ f.write(erb.result binding)
91
+ }
92
+
93
+ File.open("dossier/assets/dossier.min.css", 'w') { |f|
94
+ engine = Sass::Engine.new(File.open("#{__dir__}/../app/assets/stylesheets/dossier.scss").read, :syntax => :scss, :load_paths => ["#{__dir__}/../app/assets/stylesheets/vendor"])
95
+
96
+ f.write(CSSminify.compress(engine.render))
97
+ }
98
+
99
+ FileUtils.copy_entry "#{__dir__}/../app", "dossier/"
100
+
101
+ else
102
+ puts "\e[31mThere is no branch called '#{branch}'.\e[0m"
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,3 @@
1
+ module GitDossier
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git_dossier
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ivan Bozic
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-25 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Git Dossier is a tool to generate static websites that visualize your
14
+ git repository in a beautiful way.
15
+ email: ivan@arsfutura.co
16
+ executables:
17
+ - git_dossier
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - ".gitignore"
22
+ - Gemfile
23
+ - Gemfile.lock
24
+ - LICENSE
25
+ - README.md
26
+ - app/assets/javascripts/gradient.js
27
+ - app/assets/stylesheets/dossier.scss
28
+ - app/assets/stylesheets/vendor/_normalize.scss
29
+ - app/views/index.html.erb
30
+ - bin/git_dossier
31
+ - git_dossier.gemspec
32
+ - lib/git_dossier.rb
33
+ - lib/git_dossier/version.rb
34
+ homepage: http://ivanbozic.com/git-dossier/
35
+ licenses:
36
+ - MIT
37
+ metadata: {}
38
+ post_install_message:
39
+ rdoc_options: []
40
+ require_paths:
41
+ - lib
42
+ required_ruby_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ required_rubygems_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ requirements: []
53
+ rubyforge_project:
54
+ rubygems_version: 2.4.8
55
+ signing_key:
56
+ specification_version: 4
57
+ summary: A beautiful way to visualize your git repository.
58
+ test_files: []