Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 38 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,23 +34,23 @@ This GitHub Action collects your GitHub data and coding activity from WakaTime.
## Usage

### Environment Variables
| Name | Description | Required | Default |
|---------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|---------------------------|
| `GITHUB_TOKEN` | The GitHub token to authenticate API requests. | Yes | - |
| `SHOW_METRICS` | The metrics to show in the `README.md` file. | Yes | - |
| `WAKATIME_API_KEY` | The WakaTime API key to fetch coding activity statistics. | No | - |
| `WAKATIME_RANGE` | The range for WakaTime statistics (e.g., `last_7_days`, `last_30_days`, `last_6_months`, `last_year`, `all_time`). | No | last_7_days |
| `WAKATIME_DATA` | The data to show from WakaTime statistics. | If `WAKATIME_API_KEY` is provided | - |
| `TIME_ZONE` | The timezone to use for statistics. | No | UTC |
| `TIME_LAYOUT` | The layout of the time to show in the last update time. | No | 2006-01-02 15:04:05 -0700 |
| `SHOW_LAST_UPDATE` | Whether to show the last update time in the `README.md` file. | No | - |
| `ONLY_MAIN_BRANCH` | Whether to fetch data only from the main branch. If you don’t set this, it will search for commits in all branches of the repository to count the number of commits, which might take more time. | No | - |
| `COMMIT_MESSAGE` | The commit message to use when updating the `README.md`. | No | 📝 Update README.md |
| `COMMIT_USER_NAME` | The name to use for the commit. | No | GitHub Action |
| `COMMIT_USER_EMAIL` | The email to use for the commit. | No | action@github.com |
| `SECTION_NAME` | The section name in the `README.md` to update. | No | readme-stats |
| `HIDE_REPO_INFO` | Whether to hide the repository information in action logs. | No | - |

| Name | Description | Required | Default |
|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------|---------------------------|
| `GITHUB_TOKEN` | The GitHub token to authenticate API requests. | Yes | - |
| `SHOW_METRICS` | The metrics to show in the `README.md` file. | Yes | - |
| `WAKATIME_API_KEY` | The WakaTime API key to fetch coding activity statistics. | No | - |
| `WAKATIME_RANGE` | The range for WakaTime statistics (e.g., `last_7_days`, `last_30_days`, `last_6_months`, `last_year`, `all_time`). | No | last_7_days |
| `WAKATIME_DATA` | The data to show from WakaTime statistics. | If `WAKATIME_API_KEY` is provided | - |
| `TIME_ZONE` | The timezone to use for statistics. | No | UTC |
| `TIME_LAYOUT` | The layout of the time to show in the last update time. | No | 2006-01-02 15:04:05 -0700 |
| `SHOW_LAST_UPDATE` | Whether to show the last update time in the `README.md` file. | No | - |
| `ONLY_MAIN_BRANCH` | Whether to fetch data only from the main branch. If you don’t set this, it will search for commits in all branches of the repository to count the number of commits, which might take more time. | No | - |
| `COMMIT_MESSAGE` | The commit message to use when updating the `README.md`. | No | 📝 Update README.md |
| `COMMIT_USER_NAME` | The name to use for the commit. | No | GitHub Action |
| `COMMIT_USER_EMAIL` | The email to use for the commit. | No | action@github.com |
| `SECTION_NAME` | The section name in the `README.md` to update. | No | readme-stats |
| `HIDE_REPO_INFO` | Whether to hide the repository information in action logs. | No | - |
| `PROGRESS_BAR_VERSION` | The version of the progress bar to use. | No | 1 |
### Metrics
The `SHOW_METRICS` environment variable is used to specify the metrics to show in the `README.md` file. You can choose from the following metrics:

Expand Down Expand Up @@ -89,17 +89,16 @@ The `SHOW_METRICS` environment variable is used to specify the metrics to show i

**💬 Languages**

![JavaScript](https://img.shields.io/badge/JavaScript-67.8%25-f1e05a?&logo=JavaScript&labelColor=000)
![Python](https://img.shields.io/badge/Python-44.1%25-3572A5?&logo=Python&labelColor=000)
![Java](https://img.shields.io/badge/Java-40.2%25-b07219?&logo=Java&labelColor=000)
![C#](https://img.shields.io/badge/C%23-31.4%25-178600?&logo=CSharp&labelColor=000)
![PHP](https://img.shields.io/badge/PHP-26.2%25-4F5D95?&logo=PHP&labelColor=000)
![C++](https://img.shields.io/badge/C++-23.5%25-00599C?&logo=Cplusplus&labelColor=000)
![TypeScript](https://img.shields.io/badge/TypeScript-21.2%25-3178C6?&logo=TypeScript&labelColor=000)
![Ruby](https://img.shields.io/badge/Ruby-10.5%25-701516?&logo=Ruby&labelColor=000)
![Swift](https://img.shields.io/badge/Swift-8.9%25-FA7343?&logo=Swift&labelColor=000)
![Go](https://img.shields.io/badge/Go-7.3%25-00ADD8?&logo=Go&labelColor=000)

![JavaScript](https://img.shields.io/badge/JavaScript-20.0%25-f1e05a?&logo=JavaScript&labelColor=151b23)
![Python](https://img.shields.io/badge/Python-13.0%25-3572A5?&logo=Python&labelColor=151b23)
![Java](https://img.shields.io/badge/Java-12.0%25-b07219?&logo=Java&labelColor=151b23)
![C#](https://img.shields.io/badge/C%23-9.4%25-178600?&logo=CSharp&labelColor=151b23)
![PHP](https://img.shields.io/badge/PHP-7.8%25-4F5D95?&logo=PHP&labelColor=151b23)
![C++](https://img.shields.io/badge/C++-7.0%25-00599C?&logo=Cplusplus&labelColor=151b23)
![TypeScript](https://img.shields.io/badge/TypeScript-6.3%25-3178C6?&logo=TypeScript&labelColor=151b23)
![Ruby](https://img.shields.io/badge/Ruby-3.1%25-701516?&logo=Ruby&labelColor=151b23)
![Swift](https://img.shields.io/badge/Swift-2.6%25-FA7343?&logo=Swift&labelColor=151b23)
![Go](https://img.shields.io/badge/Go-2.8%25-00ADD8?&logo=Go&labelColor=151b23)

**WAKATIME_SPENT_TIME**: The time you spent coding on WakaTime.

Expand Down Expand Up @@ -149,6 +148,17 @@ You can use the `WAKATIME_RANGE` environment variable to set the time range for

**Note**: If you don't provide the `WAKATIME_API_KEY`, the `WAKATIME_SPENT_TIME` metric will not be shown.

### Progress Bar Versions
You can use the `PROGRESS_BAR_VERSION` environment variable to specify the version of the progress bar to use. The available versions are:
+ `1`: **Default Progress Bar**: Uses the default progress bar style.
```
████░░░░░░░░░░░░░░░░░░░░░
```
+ `2` **Square Symbol Progress Bar**: Uses the square symbol for the progress bar. This version also shows the half block (the remaining percentage is not enough to fill a whole block) for the progress bar.
```
🟩🟩🟩🟩🟩🟩🟩🟩🟨⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜
```

### Example Workflow

```yaml
Expand Down
87 changes: 70 additions & 17 deletions pkg/writer/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package writer
import (
"fmt"
"math"
"os"
"sort"
"strings"
"time"
"unicode/utf8"
Expand Down Expand Up @@ -45,11 +47,17 @@ func MakeLanguageUsedList(l map[string][2]interface{}, totalSize int) string {
return ""
}

// Create a map to store the sizes for sorting
sizeMap := make(map[string]int)
for key, value := range l {
sizeMap[key] = value[1].(int)
}

res := strings.Builder{}
for k, v := range l {
c := v[0].(string)
s := v[1].(int)
res.WriteString(fmt.Sprintf("![%s](https://img.shields.io/badge/%s-%05.2f%%25-%s?&logo=%s&labelColor=000)\n", k, k, float64(s)/float64(totalSize)*100, c[1:], k))
for _, k := range sortMapByValue(sizeMap) {
c := l[k][0].(string)
s := l[k][1].(int)
res.WriteString(fmt.Sprintf("![%s](https://img.shields.io/badge/%s-%05.2f%%25-%s?&logo=%s&labelColor=151b23)\n", k, k, float64(s)/float64(totalSize)*100, c[1:], k))
}

return "**💬 Languages**\n\n" + res.String() + "\n\n"
Expand Down Expand Up @@ -254,7 +262,8 @@ func MakeLanguagePerRepoList(r []github.Repository) string {
}

// Create a list of Data structs
for name, num := range repos {
for _, name := range sortMapByValue(repos) {
num := repos[name]
if num > topNum { // find top language
topNum = num
topName = name
Expand All @@ -266,7 +275,6 @@ func MakeLanguagePerRepoList(r []github.Repository) string {
if num > 1 {
return "repos"
}

return "repo"
}()),
Percent: float64(num) / count * 100,
Expand All @@ -281,36 +289,67 @@ func makeList(d ...Data) string {
return "\nNo data available\n"
}

var b strings.Builder
for _, v := range d {
b.WriteString(formatData(v))
var (
b strings.Builder
ver = os.Getenv("PROGRESS_BAR_VERSION")
)

for _, val := range d {
b.WriteString(formatData(val, ver))
}

b.WriteString("\n")

return b.String()
}

func makeGraph(p float64) string {
d, e, q := "█", "░", math.Round(p/(100/graphLength))
func makeProgressBar(p float64) string {
filledChar := "█"
emptyChar := "░"

filledLength := int(math.Round(p / (100 / graphLength)))
emptyLength := graphLength - filledLength

return strings.Repeat(filledChar, filledLength) + strings.Repeat(emptyChar, emptyLength)
}

func makeProgressBarV2(p float64) string {
filledChar := "🟩"
halfFilledChar := "🟨"
emptyChar := "⬜"

percentagePerBlock := float64(100 / graphLength)
filledLength := int(math.Floor(p / percentagePerBlock))
remainingPercentage := p - (float64(filledLength) * percentagePerBlock)
halfFilledLength := 0
if remainingPercentage > 0 {
halfFilledLength = 1
}
emptyLength := graphLength - filledLength - halfFilledLength

return strings.Repeat(d, int(q)) + strings.Repeat(e, graphLength-int(q))
return strings.Repeat(filledChar, filledLength) + strings.Repeat(halfFilledChar, halfFilledLength) + strings.Repeat(emptyChar, emptyLength)
}

func formatData(v Data) string {
func formatData(data Data, version string) string {
var b strings.Builder

n := truncateString(v.Name, nameLength)
d := truncateString(v.Description, descriptionLength)
n := truncateString(data.Name, nameLength)
d := truncateString(data.Description, descriptionLength)

b.WriteString("\n")
b.WriteString(n)
b.WriteString(strings.Repeat(" ", nameLength-utf8.RuneCountInString(n)))
b.WriteString(d)
b.WriteString(strings.Repeat(" ", descriptionLength-utf8.RuneCountInString(d)))
b.WriteString(makeGraph(v.Percent))

if version == "2" {
b.WriteString(makeProgressBarV2(data.Percent))
} else {
b.WriteString(makeProgressBar(data.Percent))
}

b.WriteString(" ")
b.WriteString(formatPercent(v.Percent))
b.WriteString(formatPercent(data.Percent))

return b.String()
}
Expand Down Expand Up @@ -364,3 +403,17 @@ func formatTime(hours, minutes int) string {

return strings.TrimSpace(result)
}

// sortMapByValue sorts a map by its values in descending order
func sortMapByValue(m map[string]int) []string {
keys := make([]string, 0, len(m))
for key := range m {
keys = append(keys, key)
}

sort.Slice(keys, func(i, j int) bool {
return m[keys[i]] > m[keys[j]]
})

return keys
}