Skip to content

Added hackatime-doctor #397

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
150 changes: 150 additions & 0 deletions docs/hackatime-doctor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
# HackaTime Doctor ⚕️

![Terminal Screenshot](terminal-screenshot.png)

A diagnostic tool that verifies your development environment meets all requirements for Hack Club's HackaTime and help in its setup and fixing.

## Features

### Core Checks
- ✅ Git installation check
- ✅ API connectivity test (HackaTime server)
- ✅ WakaTime config validation

### Optional Checks
- ✅ Project structure validation (README.md, LICENSE, .gitignore)
- ✅ Node.js installation & version check (v16+)

### Installation & Setup
- 🔄 Auto-install for missing packages
- 🔍 Multi-package manager support:
- Windows: Chocolatey (`choco`)
- macOS: Homebrew (`brew`)
- Linux:
- APT (Debian/Ubuntu)
- DNF/YUM (RHEL/Fedora)
- Pacman (Arch)
- Zypper (openSUSE)
- APK (Alpine)
- And many other package systems
- ⚙️ Interactive WakaTime config setup
- 🔐 Secure API key handling

### Reporting & Output
- 📊 JSON report generation
- 📈 CSV report generation
- 🎨 Color-coded terminal output
- 📋 Detailed error messages with remediation steps

### Cross-Platform Support
- 🖥️ Windows compatibility
- 🍏 macOS compatibility
- 🐧 Linux compatibility
- 🔄 Automatic path resolution (WAKATIME_HOME, XDG_CONFIG_HOME, etc.)

### Advanced Features
- 📂 Multi-location config file detection:
- `~/.wakatime.cfg`
- `~/.config/wakatime/.wakatime.cfg`
- `/etc/wakatime.cfg`
- 🚦 Environment variable validation

### Quick Install (Recommended)

Download the latest release for your platform:

**[📥 Download Latest Release](https://github.com/arungeorgesaji/hackatime-doctor/releases/latest)**

#### Windows
1. Download the Windows release (`.zip` file)
2. Extract the zip file to your desired location
3. Open PowerShell in the extracted folder
4. Choco (Chocolatey) is required for the installation. If you don't have it installed, follow these steps:

1. Open PowerShell as Administrator
2. Run the following command to install Chocolatey:

```powershell
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
```

5. Install OpenSSL if not already installed (required for HTTPS requests), follow these steps:

1. Open PowerShell as Administrator
2. Run the following command to install OpenSSL:

```powershell
choco install openssl
```
6. Set console encoding to UTF-8 (recommended for proper output display in powershell):

```powershell
# Temporary (for current session only):
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8

# Permanent (add to PowerShell profile):
Add-Content -Path $PROFILE -Value "[Console]::OutputEncoding = [System.Text.Encoding]::UTF8"
```

6. Run the executable directly from the extracted folder, or for global access, copy hackatime-doctor.exe to a directory in your system PATH (like C:\Program Files\HackaTime Doctor)
Note: You may need to run PowerShell as Administrator while running the script.

#### Linux/macOS
1. Download the appropriate release for your platform in your desired location
2. Extract the archive:

```bash
tar -xzf hackatime-doctor-*.tar.gz
```
3. Run the installation script:

```bash
chmod +x install.sh
sudo ./install.sh
```

Note: Some minimal linux distros may not have which installedby default, most likely you wouldnt face an issue with this
command, but if you do, you can install it using your package manager.

### Build from Source

If you prefer to compile from source:

```bash
git clone https://github.com/arungeorgesaji/hackatime-doctor.git
cd hackatime-doctor
make
sudo make install
```

## Usage

After installation, run the diagnostic tool:

```bash
hackatime-doctor
```

Run extended diagnostics including project structure checks and checks for popular developer packages:

```bash
hackatime-doctor --full-check
```

> 🚧 **Beta Feature**
> The `--full-check` currently includes basic extended validation.

## Output Formats

Generate reports in multiple formats:

```bash
# Output to terminal
hackatime-doctor

# JSON report
hackatime-doctor --json

# CSV report
hackatime-doctor --csv
```
Binary file added docs/hackatime-doctor/terminal-screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
83 changes: 83 additions & 0 deletions public/hackatime/hackatime-doctor/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
CXX := g++
MKDIR := mkdir -p
RM := rm -rf

SRC_DIR := src
INCLUDE_DIR := include
OBJ_DIR := obj
BUILD_DIR := bin
TEST_DIR := tests

SRCS := $(wildcard $(SRC_DIR)/*.cpp)
MAIN_SRC := $(SRC_DIR)/main.cpp
CHECK_SRCS := $(filter-out $(MAIN_SRC), $(SRCS))
OBJS := $(patsubst $(SRC_DIR)/%.cpp,$(OBJ_DIR)/%.o,$(SRCS))
MAIN_OBJ := $(OBJ_DIR)/main.o
CHECK_OBJS := $(filter-out $(MAIN_OBJ), $(OBJS))
DEPS := $(OBJS:.o=.d)

TARGET := $(BUILD_DIR)/hackatime-doctor
TEST_TARGET := $(BUILD_DIR)/hackatime-tests

CXXFLAGS := -std=c++17 -Wall -Wextra -pedantic -I$(INCLUDE_DIR)
DEBUG_FLAGS := -g -O0
RELEASE_FLAGS := -O3 -DNDEBUG

LDFLAGS := -lssl -lcrypto
TEST_LDFLAGS := -lgtest -lgtest_main -lpthread

BUILD_TYPE ?= debug
ifeq ($(BUILD_TYPE),release)
CXXFLAGS += $(RELEASE_FLAGS)
else
CXXFLAGS += $(DEBUG_FLAGS)
endif

all: $(TARGET)

$(TARGET): $(OBJS)
@$(MKDIR) $(@D)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS)

test: $(TEST_TARGET)
@$(TEST_TARGET)

$(TEST_TARGET): $(CHECK_OBJS) $(TEST_DIR)/tests.cpp
@$(MKDIR) $(@D)
$(CXX) $(CXXFLAGS) $^ -o $@ $(LDFLAGS) $(TEST_LDFLAGS)

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.cpp
@$(MKDIR) $(@D)
$(CXX) $(CXXFLAGS) -MMD -MP -c $< -o $@

-include $(DEPS)

release: BUILD_TYPE=release
release: clean all

install:
@echo "To install, copy $(TARGET) to a directory in your PATH"
@echo "Example: sudo cp $(TARGET) /usr/local/bin/"

uninstall:
@echo "To uninstall, remove the binary from your PATH"
@echo "Example: sudo rm /usr/local/bin/hackatime-doctor"

format:
find $(SRC_DIR) $(INCLUDE_DIR) -name '*.cpp' -o -name '*.h' | xargs clang-format -i

clean:
$(RM) $(OBJ_DIR) $(BUILD_DIR)

help:
@echo "Available targets:"
@echo " all - Build the application (debug mode)"
@echo " release - Build optimized release version"
@echo " test - Build and run tests"
@echo " clean - Clean build files"
@echo " format - Format source code with clang-format"
@echo " install - Show install instructions"
@echo " uninstall- Show uninstall instructions"
@echo " help - Show this help"

.PHONY: all test clean install uninstall format release help
48 changes: 48 additions & 0 deletions public/hackatime/hackatime-doctor/include/checks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef CHECKS_H
#define CHECKS_H

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <ctime>
#include <fstream>
#include <regex>
#include <sstream>
#include <iostream>

#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#else
#error "No filesystem support!"
#endif

#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <shlobj.h>
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "crypt32.lib")
#define close_socket closesocket
using socket_t = SOCKET;
#else
#include <wordexp.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <arpa/inet.h>
#define close_socket close
using socket_t = int;
#define INVALID_SOCKET -1
#endif

#include <openssl/ssl.h>
#include <openssl/err.h>

#endif
31 changes: 31 additions & 0 deletions public/hackatime/hackatime-doctor/include/hackatime_doctor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef HACKATIME_DOCTOR_H
#define HACKATIME_DOCTOR_H

#include <string>
#include <vector>

#define COLOR_RED "\x1b[31m"
#define COLOR_GREEN "\x1b[32m"
#define COLOR_YELLOW "\x1b[33m"
#define COLOR_BLUE "\x1b[34m"
#define COLOR_RESET "\x1b[0m"

struct CheckResult {
bool success;
std::string message;
std::string name;

CheckResult(bool s, std::string m, std::string n = "")
: success(s), message(std::move(m)), name(std::move(n)) {}
};

CheckResult check_wakatime_config();
CheckResult check_git_installed();
CheckResult check_node_installed();
CheckResult check_folder_structure();
CheckResult check_api_tokens();
void print_summary(const std::vector<CheckResult>& results);
void suggest_debug_tips(const std::vector<CheckResult>& results);
int run_hackatime_doctor(int argc, char* argv[]);

#endif
12 changes: 12 additions & 0 deletions public/hackatime/hackatime-doctor/include/main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef OUTPUT_H
#define OUTPUT_H

#include <iostream>
#include <algorithm>
#include <nlohmann/json.hpp>
#include <fstream>
#include <iomanip>

using json = nlohmann::json;

#endif
7 changes: 7 additions & 0 deletions public/hackatime/hackatime-doctor/include/output.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef OUTPUT_H
#define OUTPUT_H

#include <iostream>
#include <vector>

#endif
Loading