Add new plugin habits
This commit is contained in:
52
README.md
52
README.md
@@ -106,6 +106,9 @@ jobs:
|
|||||||
# The provided GitHub token will require "repo" permissions
|
# The provided GitHub token will require "repo" permissions
|
||||||
plugin_traffic: no
|
plugin_traffic: no
|
||||||
|
|
||||||
|
# Enable or disable coding habits metrics
|
||||||
|
plugin_habits: no
|
||||||
|
|
||||||
# Enable debug logs
|
# Enable debug logs
|
||||||
debug: no
|
debug: no
|
||||||
|
|
||||||
@@ -273,6 +276,17 @@ Open and edit `settings.json` to configure your instance.
|
|||||||
//When enabled, pass "?traffic=1" in url to compute total page views in your repositories in last two weeks
|
//When enabled, pass "?traffic=1" in url to compute total page views in your repositories in last two weeks
|
||||||
//Note that this requires that the passed GitHub API token requires a push access
|
//Note that this requires that the passed GitHub API token requires a push access
|
||||||
"enabled":true
|
"enabled":true
|
||||||
|
},
|
||||||
|
//Habits plugin
|
||||||
|
"habits":{
|
||||||
|
//Enable or disable this plugin
|
||||||
|
//When enabled, pass "?habits=1" in url to generate coding habits based on your recent activity
|
||||||
|
//This includes stuff like if you're using tabs or space and the time of the day when you push the most
|
||||||
|
//Note that this requires that the passed GitHub API token requires a push access
|
||||||
|
"enabled":true,
|
||||||
|
//Specify the number of events used to compute coding habits. Capped at 100 by GitHub API
|
||||||
|
//Defaults to 50
|
||||||
|
"from":50,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -485,6 +499,44 @@ And pass `?traffic=1` in url when generating metrics.
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
#### 💡 Habits
|
||||||
|
|
||||||
|
The *habits* plugin allows you to add deduced coding about based on your recent activity.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>💬 About</summary>
|
||||||
|
|
||||||
|
It will consume an additional GitHub request per event fetched.
|
||||||
|
|
||||||
|
##### Setup with GitHub actions
|
||||||
|
|
||||||
|
Add the following to your workflow :
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- uses: lowlighter/metrics@latest
|
||||||
|
with:
|
||||||
|
# ... other options
|
||||||
|
plugin_habits: yes
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Setup in your own instance
|
||||||
|
|
||||||
|
Add the following to your `settings.json`
|
||||||
|
|
||||||
|
```json
|
||||||
|
"plugins":{
|
||||||
|
"habits":{
|
||||||
|
"enabled":true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And pass `?habits=1` in url when generating metrics.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
### 🗂️ Project structure
|
### 🗂️ Project structure
|
||||||
|
|
||||||
* `index.mjs` contains the entry points and the settings instance
|
* `index.mjs` contains the entry points and the settings instance
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ inputs:
|
|||||||
description: Enable repositories lines metrics
|
description: Enable repositories lines metrics
|
||||||
plugin_traffic:
|
plugin_traffic:
|
||||||
description: Enable repositories traffic metrics (due to GitHub API limitations, "token" must have "repo" permissions)
|
description: Enable repositories traffic metrics (due to GitHub API limitations, "token" must have "repo" permissions)
|
||||||
|
plugin_habits:
|
||||||
|
description: Enable coding habits metrics
|
||||||
debug:
|
debug:
|
||||||
description: Enable debug logs
|
description: Enable debug logs
|
||||||
runs:
|
runs:
|
||||||
|
|||||||
35
action/dist/index.js
vendored
35
action/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@@ -42,6 +42,7 @@
|
|||||||
lines:{enabled:core.getInput("plugin_lines", {default:false})},
|
lines:{enabled:core.getInput("plugin_lines", {default:false})},
|
||||||
traffic:{enabled:core.getInput("plugin_traffic", {default:false})},
|
traffic:{enabled:core.getInput("plugin_traffic", {default:false})},
|
||||||
pagespeed:{enabled:core.getInput("plugin_pagespeed", {default:false})},
|
pagespeed:{enabled:core.getInput("plugin_pagespeed", {default:false})},
|
||||||
|
habits:{enabled:core.getInput("plugin_habits", {default:false})},
|
||||||
}
|
}
|
||||||
if (core.getInput("pagespeed_token")) {
|
if (core.getInput("pagespeed_token")) {
|
||||||
console.log(`Pagespeed token | provided`)
|
console.log(`Pagespeed token | provided`)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "metrics",
|
"name": "metrics",
|
||||||
"version": "1.6.0",
|
"version": "1.7.0",
|
||||||
"description": "Generate an user's GitHub metrics as SVG image format to embed somewhere else",
|
"description": "Generate an user's GitHub metrics as SVG image format to embed somewhere else",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -16,7 +16,11 @@
|
|||||||
"enabled":true, "//":"Enable or disable repositories total page views is last two weeks"
|
"enabled":true, "//":"Enable or disable repositories total page views is last two weeks"
|
||||||
},
|
},
|
||||||
"lines":{ "//":"Lines plugin",
|
"lines":{ "//":"Lines plugin",
|
||||||
"enabled":true, "//":"Enable or disabled repositories total lines added/removed"
|
"enabled":true, "//":"Enable or disable repositories total lines added/removed"
|
||||||
|
},
|
||||||
|
"habits":{ "//":"Habits plugin",
|
||||||
|
"enabled":true, "//":"Enable or disable coding habits metrics",
|
||||||
|
"from":50, "//":"Number of activity events to base habits on (up to 100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,12 @@
|
|||||||
|
|
||||||
<h1><a href="https://github.com/lowlighter/metrics">GitHub metrics</a></h1>
|
<h1><a href="https://github.com/lowlighter/metrics">GitHub metrics</a></h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Enter your GitHub username below to generate your metrics.
|
||||||
|
</p>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
<input type="text" name="user" placeholder="Your GitHub username" value="">
|
<input type="text" name="user" placeholder="@username" value="">
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div id="metrics">
|
<div id="metrics">
|
||||||
@@ -26,8 +30,8 @@
|
|||||||
<div class="code">
|
<div class="code">
|
||||||

|

|
||||||
</div>
|
</div>
|
||||||
<br>
|
For even more metrics (coding habits, PageSpeed performances, number of line of code you wrote, page views, etc.), setup this as a <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> on your repository !<br>
|
||||||
And for even more metrics, setup this <a href="https://github.com/marketplace/actions/github-metrics-as-svg-image">GitHub action</a> on your repository !
|
Check out <a href="https://github.com/lowlighter/metrics">lowlighter/metrics</a> for more informations
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -50,14 +54,19 @@
|
|||||||
if (event.key === "Enter")
|
if (event.key === "Enter")
|
||||||
metrics(user)
|
metrics(user)
|
||||||
else
|
else
|
||||||
timeout = setTimeout(() => metrics(user), 2000)
|
timeout = setTimeout(() => metrics(user), 1800)
|
||||||
}
|
}
|
||||||
//Metrics updater
|
//Metrics updater
|
||||||
let current = null
|
let current = null
|
||||||
function metrics(user) {
|
function metrics(user) {
|
||||||
if (!user.trim().length)
|
if (!user.trim().length)
|
||||||
return
|
return
|
||||||
if (current !== user) {
|
if (current === user) {
|
||||||
|
document.querySelector("#metrics .placeholder").style.opacity = 0
|
||||||
|
document.querySelector("#metrics .generated").style.opacity = 1
|
||||||
|
document.querySelector("aside").style.opacity = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
current = user
|
current = user
|
||||||
document.querySelector("#metrics .generated").src = `https://metrics.lecoq.io/${user}`
|
document.querySelector("#metrics .generated").src = `https://metrics.lecoq.io/${user}`
|
||||||
document.querySelector("#metrics .generated").onload = function () {
|
document.querySelector("#metrics .generated").onload = function () {
|
||||||
@@ -86,7 +95,7 @@
|
|||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
h1 {
|
h1 {
|
||||||
margin-top: 4rem
|
margin: 4rem 0 0;
|
||||||
}
|
}
|
||||||
a, a:hover, a:visited {
|
a, a:hover, a:visited {
|
||||||
color: #0366D6;
|
color: #0366D6;
|
||||||
@@ -117,7 +126,7 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
width: 480px;
|
width: 480px;
|
||||||
height: 516px;
|
height: 485px;
|
||||||
}
|
}
|
||||||
#metrics img {
|
#metrics img {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -131,7 +140,7 @@
|
|||||||
padding: .25rem;
|
padding: .25rem;
|
||||||
transition: opacity .4s;
|
transition: opacity .4s;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 2rem;
|
margin: 1rem 0 2rem;
|
||||||
}
|
}
|
||||||
.code {
|
.code {
|
||||||
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
font-family: SFMono-Regular,Consolas,Liberation Mono,Menlo,monospace;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="516">
|
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="485">
|
||||||
<style>
|
<style>
|
||||||
/* SVG global context */
|
/* SVG global context */
|
||||||
svg {
|
svg {
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
@@ -28,6 +28,7 @@
|
|||||||
Plugins.pagespeed({login, url:data.user.websiteUrl, computed, pending, q}, plugins.pagespeed)
|
Plugins.pagespeed({login, url:data.user.websiteUrl, computed, pending, q}, plugins.pagespeed)
|
||||||
Plugins.lines({login, repositories:data.user.repositories.nodes.map(({name}) => name), rest, computed, pending, q}, plugins.lines)
|
Plugins.lines({login, repositories:data.user.repositories.nodes.map(({name}) => name), rest, computed, pending, q}, plugins.lines)
|
||||||
Plugins.traffic({login, repositories:data.user.repositories.nodes.map(({name}) => name), rest, computed, pending, q}, plugins.traffic)
|
Plugins.traffic({login, repositories:data.user.repositories.nodes.map(({name}) => name), rest, computed, pending, q}, plugins.traffic)
|
||||||
|
Plugins.habits({login, rest, computed, pending, q}, plugins.habits)
|
||||||
|
|
||||||
//Iterate through user's repositories
|
//Iterate through user's repositories
|
||||||
for (const repository of data.user.repositories.nodes) {
|
for (const repository of data.user.repositories.nodes) {
|
||||||
|
|||||||
57
src/plugins/habits/index.mjs
Normal file
57
src/plugins/habits/index.mjs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
//Setup
|
||||||
|
export default function ({login, rest, computed, pending, q}, {enabled = false, from = 50} = {}) {
|
||||||
|
//Check if plugin is enabled and requirements are met
|
||||||
|
if (!enabled)
|
||||||
|
return computed.plugins.habits = null
|
||||||
|
if (!q.habits)
|
||||||
|
return computed.plugins.habits = null
|
||||||
|
console.debug(`metrics/plugins/habits/${login} > started`)
|
||||||
|
|
||||||
|
//Plugin execution
|
||||||
|
pending.push(new Promise(async solve => {
|
||||||
|
try {
|
||||||
|
//Initialization
|
||||||
|
const habits = {commits:{hour:NaN, hours:{}}, indents:{style:"", spaces:0, tabs:0}}
|
||||||
|
//Get user recent commits from events
|
||||||
|
const events = await rest.activity.listEventsForAuthenticatedUser({username:login, per_page:from})
|
||||||
|
const commits = events.data
|
||||||
|
.filter(({type}) => type === "PushEvent")
|
||||||
|
.filter(({actor}) => actor.login === login)
|
||||||
|
//Commit hour
|
||||||
|
{
|
||||||
|
//Compute commit hours
|
||||||
|
const hours = commits.map(({created_at}) => (new Date(created_at)).getHours())
|
||||||
|
for (const hour of hours)
|
||||||
|
habits.commits.hours[hour] = (habits.commits.hours[hour] || 0) + 1
|
||||||
|
//Compute hour with most commits
|
||||||
|
habits.commits.hour = hours.length ? Object.entries(habits.commits.hours).sort(([an, a], [bn, b]) => b - a).map(([hour, occurence]) => hour)[0] : NaN
|
||||||
|
}
|
||||||
|
//Indent style
|
||||||
|
{
|
||||||
|
//Retrieve edited files
|
||||||
|
const edited = await Promise.allSettled(commits
|
||||||
|
.flatMap(({payload}) => payload.commits).map(commit => commit.url)
|
||||||
|
.map(async commit => (await rest.request(commit)).data.files)
|
||||||
|
)
|
||||||
|
//Attemp to guess whether tabs or spaces are used from patch
|
||||||
|
edited
|
||||||
|
.filter(({status}) => status === "fulfilled")
|
||||||
|
.map(({value}) => value)
|
||||||
|
.flatMap(files => files.flatMap(file => (file.patch||"").match(/(?<=^[+])((?:\t)|(?: )) /gm)||[]))
|
||||||
|
.forEach(indent => habits.indents[/^\t/.test(indent) ? "tabs" : "spaces"]++)
|
||||||
|
//Compute indent style
|
||||||
|
habits.indents.style = habits.indents.spaces > habits.indents.tabs ? "spaces" : habits.indents.tabs > habits.indents.spaces ? "tabs" : ""
|
||||||
|
}
|
||||||
|
//Save results
|
||||||
|
computed.plugins.habits = habits
|
||||||
|
console.debug(`metrics/plugins/habits/${login} > ${JSON.stringify(computed.plugins.habits)}`)
|
||||||
|
solve()
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
//Generic error
|
||||||
|
computed.plugins.habits = {error:`An error occured`}
|
||||||
|
console.debug(error)
|
||||||
|
solve()
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
//Imports
|
//Imports
|
||||||
|
import habits from "./habits/index.mjs"
|
||||||
import lines from "./lines/index.mjs"
|
import lines from "./lines/index.mjs"
|
||||||
import pagespeed from "./pagespeed/index.mjs"
|
import pagespeed from "./pagespeed/index.mjs"
|
||||||
import traffic from "./traffic/index.mjs"
|
import traffic from "./traffic/index.mjs"
|
||||||
|
|
||||||
//Exports
|
//Exports
|
||||||
export default {
|
export default {
|
||||||
|
habits,
|
||||||
lines,
|
lines,
|
||||||
pagespeed,
|
pagespeed,
|
||||||
traffic,
|
traffic,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
console.debug(`metrics/plugins/lines/${login} > started`)
|
console.debug(`metrics/plugins/lines/${login} > started`)
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async (solve, reject) => {
|
pending.push(new Promise(async solve => {
|
||||||
try {
|
try {
|
||||||
//Get contributors stats from repositories
|
//Get contributors stats from repositories
|
||||||
const lines = {added:0, deleted:0}
|
const lines = {added:0, deleted:0}
|
||||||
@@ -41,7 +41,10 @@
|
|||||||
solve()
|
solve()
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
reject(error)
|
//Generic error
|
||||||
|
computed.plugins.pagespeed = {error:`An error occured`}
|
||||||
|
console.debug(error)
|
||||||
|
solve()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
console.debug(`metrics/plugins/pagespeed/${login} > started`)
|
console.debug(`metrics/plugins/pagespeed/${login} > started`)
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async (solve, reject) => {
|
pending.push(new Promise(async solve => {
|
||||||
try {
|
try {
|
||||||
//Format url if needed
|
//Format url if needed
|
||||||
if (!/^https?:[/][/]/.test(url))
|
if (!/^https?:[/][/]/.test(url))
|
||||||
@@ -36,11 +36,12 @@
|
|||||||
if ((error.response)&&(error.response.status)) {
|
if ((error.response)&&(error.response.status)) {
|
||||||
computed.plugins.pagespeed = {url, error:`PageSpeed token error (code ${error.response.status})`}
|
computed.plugins.pagespeed = {url, error:`PageSpeed token error (code ${error.response.status})`}
|
||||||
console.debug(`metrics/plugins/traffic/${login} > ${error.response.status}`)
|
console.debug(`metrics/plugins/traffic/${login} > ${error.response.status}`)
|
||||||
solve()
|
return solve()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
console.log(error)
|
//Generic error
|
||||||
reject(error)
|
computed.plugins.pagespeed = {error:`An error occured`}
|
||||||
|
console.debug(error)
|
||||||
|
solve()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
console.debug(`metrics/plugins/traffic/${login} > started`)
|
console.debug(`metrics/plugins/traffic/${login} > started`)
|
||||||
|
|
||||||
//Plugin execution
|
//Plugin execution
|
||||||
pending.push(new Promise(async (solve, reject) => {
|
pending.push(new Promise(async solve => {
|
||||||
try {
|
try {
|
||||||
//Get views stats from repositories
|
//Get views stats from repositories
|
||||||
const views = {count:0, uniques:0}
|
const views = {count:0, uniques:0}
|
||||||
@@ -36,10 +36,12 @@
|
|||||||
if (error.status === 403) {
|
if (error.status === 403) {
|
||||||
computed.plugins.traffic = {error:`Insufficient token rights`}
|
computed.plugins.traffic = {error:`Insufficient token rights`}
|
||||||
console.debug(`metrics/plugins/traffic/${login} > ${error.status}`)
|
console.debug(`metrics/plugins/traffic/${login} > ${error.status}`)
|
||||||
solve()
|
return solve()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
reject(error)
|
//Generic error
|
||||||
|
computed.plugins.traffic = {error:`An error occured`}
|
||||||
|
console.debug(error)
|
||||||
|
solve()
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -107,6 +107,13 @@
|
|||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Habits */
|
||||||
|
.habits {
|
||||||
|
margin: 0;
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 37px;
|
||||||
|
}
|
||||||
|
|
||||||
/* Footer */
|
/* Footer */
|
||||||
footer {
|
footer {
|
||||||
margin-top: 8px;
|
margin-top: 8px;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="${536 + (computed.plugins.pagespeed ? 100 : 0)}">
|
<svg xmlns="http://www.w3.org/2000/svg" width="480" height="${485 + ((computed.plugins.lines||computed.plugins.traffic) ? 20 : 0) + (computed.plugins.pagespeed ? 130 : 0) + (computed.plugins.habits ? 70 : 0)}">
|
||||||
<style>
|
<style>
|
||||||
${style}
|
${style}
|
||||||
</style>
|
</style>
|
||||||
@@ -274,6 +274,30 @@
|
|||||||
</section>` : ""
|
</section>` : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
${computed.plugins.habits ? `
|
||||||
|
<section>
|
||||||
|
<h2 class="field">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M8 1.5c-2.363 0-4 1.69-4 3.75 0 .984.424 1.625.984 2.304l.214.253c.223.264.47.556.673.848.284.411.537.896.621 1.49a.75.75 0 01-1.484.211c-.04-.282-.163-.547-.37-.847a8.695 8.695 0 00-.542-.68c-.084-.1-.173-.205-.268-.32C3.201 7.75 2.5 6.766 2.5 5.25 2.5 2.31 4.863 0 8 0s5.5 2.31 5.5 5.25c0 1.516-.701 2.5-1.328 3.259-.095.115-.184.22-.268.319-.207.245-.383.453-.541.681-.208.3-.33.565-.37.847a.75.75 0 01-1.485-.212c.084-.593.337-1.078.621-1.489.203-.292.45-.584.673-.848.075-.088.147-.173.213-.253.561-.679.985-1.32.985-2.304 0-2.06-1.637-3.75-4-3.75zM6 15.25a.75.75 0 01.75-.75h2.5a.75.75 0 010 1.5h-2.5a.75.75 0 01-.75-.75zM5.75 12a.75.75 0 000 1.5h4.5a.75.75 0 000-1.5h-4.5z"></path></svg>
|
||||||
|
Coding habits
|
||||||
|
</h2>
|
||||||
|
<div class="row">
|
||||||
|
${computed.plugins.habits.error ? `
|
||||||
|
<section>
|
||||||
|
<div class="field error">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M4.47.22A.75.75 0 015 0h6a.75.75 0 01.53.22l4.25 4.25c.141.14.22.331.22.53v6a.75.75 0 01-.22.53l-4.25 4.25A.75.75 0 0111 16H5a.75.75 0 01-.53-.22L.22 11.53A.75.75 0 010 11V5a.75.75 0 01.22-.53L4.47.22zm.84 1.28L1.5 5.31v5.38l3.81 3.81h5.38l3.81-3.81V5.31L10.69 1.5H5.31zM8 4a.75.75 0 01.75.75v3.5a.75.75 0 01-1.5 0v-3.5A.75.75 0 018 4zm0 8a1 1 0 100-2 1 1 0 000 2z"></path></svg>
|
||||||
|
${computed.plugins.habits.error}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
` : `
|
||||||
|
<ul class="habits">
|
||||||
|
${computed.plugins.habits.indents.style ? `<li>Use ${computed.plugins.habits.indents.style} for indents</li>` : ""}
|
||||||
|
${!Number.isNaN(computed.plugins.habits.commits.hour) ? `<li>Mostly push code around ${computed.plugins.habits.commits.hour}:00</li>` : ""}
|
||||||
|
</ul>
|
||||||
|
`}
|
||||||
|
</div>
|
||||||
|
</section>` : ""
|
||||||
|
}
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
Last updated ${new Date()}
|
Last updated ${new Date()}
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 31 KiB |
Reference in New Issue
Block a user