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
1 change: 1 addition & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ jobs:
actions: read
contents: read
security-events: write
pull-requests: read
steps:
- uses: actions/checkout@v6
- uses: github/codeql-action/init@v4
Expand Down
54 changes: 54 additions & 0 deletions .github/workflows/update-tracking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Update Tracking Issue

on:
issues:
types: [opened, closed, reopened]
pull_request:
types: [opened, closed, reopened]

jobs:
update-tracking:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: read
steps:
- name: Update tracking issue
uses: actions/github-script@v7
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
script: |
const trackingIssueNumber = 52;

// Get event details
const { action, number } = context.payload;
const isIssue = context.eventName === 'issues';
const item = context.payload[isIssue ? 'issue' : 'pull_request'];
const type = isIssue ? 'Issue' : 'PR';
const state = item.state;
const title = item.title;
const createdAt = new Date(item.created_at).toISOString().split('T')[0];

// Format status emoji
const statusEmoji = state === 'open' ? '🔄' :
state === 'closed' && !isIssue ? '❌' :
state === 'merged' ? '🎉' : '✅';

// Create update message
const updateMsg = `## 🤖 Automated Update

**${type} #${number}** - ${action}
- **Title**: ${title}
- **Status**: ${statusEmoji} ${state.toUpperCase()}
- **Date**: ${createdAt}
- **Action**: ${action}

*This tracking issue will be manually updated with full context periodically.*`;

// Add comment to tracking issue
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: trackingIssueNumber,
body: updateMsg
});
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,61 @@ This repository provides a comprehensive toolkit for developers, including globa

## Installation

Clone this repository to your home directory:
Choose your preferred installation method:

### Option 1: Direct Bash (Recommended)
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/bniladridas/github-dotfiles/main/setup-mac.sh)"
```

### Option 2: Homebrew
```bash
brew tap bniladridas/dotfiles https://github.com/bniladridas/github-dotfiles
brew install dotfiles
```

### Option 3: UV (Python Package Manager)
```bash
uv tool install git+https://github.com/bniladridas/github-dotfiles.git
```

### Option 4: Manual Clone
```bash
git clone https://github.com/bniladridas/github-dotfiles.git ~/github-dotfiles
cd ~/github-dotfiles
./setup-mac.sh
```

## Usage

### Authentication

Login with your GitHub account to access premium features:

```bash
# Login with GitHub OAuth
./auth/login.sh login

# Check login status
./auth/login.sh whoami

# Logout
./auth/login.sh logout
```

### Sync & Premium Features (Requires Login)

After logging in, access advanced features:

```bash
# Sync dotfiles across machines
./sync/dotfiles-sync.sh push # Backup to GitHub
./sync/dotfiles-sync.sh pull # Restore from GitHub

# Premium tools
./sync/dotfiles-sync.sh premium # Show available features
```

### Dart CLI Tool

Install Dart SDK, then use the CLI tool for managing dotfiles:
Expand Down
95 changes: 95 additions & 0 deletions auth/login.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/bin/bash

# GitHub OAuth authentication for dotfiles
AUTH_DIR="$HOME/.dotfiles"
TOKEN_FILE="$AUTH_DIR/token"
USER_FILE="$AUTH_DIR/user"

log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

github_login() {
# Check for required dependencies
if ! command -v jq &> /dev/null; then
log "ERROR: jq is required but not installed"
exit 1
fi

mkdir -p "$AUTH_DIR"

log "Opening GitHub OAuth login..."

# For now, use GitHub personal access token flow
echo "Please create a GitHub Personal Access Token:"
echo "1. Go to: https://github.com/settings/tokens"
echo "2. Click 'Generate new token (classic)'"
echo "3. Select scopes: repo, user:email"
echo "4. Copy the generated token"
echo ""

open "https://github.com/settings/tokens" 2>/dev/null || \
xdg-open "https://github.com/settings/tokens" 2>/dev/null || \
echo "Visit: https://github.com/settings/tokens"

echo "Enter your GitHub token:"
read -r -s token

if [ -n "$token" ]; then
# Validate token with GitHub API
USER_INFO=$(curl -s -H "Authorization: token $token" https://api.github.com/user)

USERNAME=$(echo "$USER_INFO" | jq -r '.login')
if [ -n "$USERNAME" ] && [ "$USERNAME" != "null" ]; then
echo "$token" > "$TOKEN_FILE"
echo "$USERNAME" > "$USER_FILE"
chmod 600 "$TOKEN_FILE" "$USER_FILE"
log "Successfully logged in as $USERNAME!"
else
log "ERROR: Invalid GitHub token"
exit 1
fi
else
log "ERROR: No token provided"
exit 1
fi
}

logout() {
if [ -f "$TOKEN_FILE" ]; then
rm -f "$TOKEN_FILE" "$USER_FILE"
log "Successfully logged out!"
else
log "Not currently logged in"
fi
}

whoami() {
if [ -f "$TOKEN_FILE" ] && [ -f "$USER_FILE" ]; then
USERNAME=$(cat "$USER_FILE")
TOKEN_PREVIEW=$(head -c 8 "$TOKEN_FILE")
log "Logged in as $USERNAME (token: ${TOKEN_PREVIEW}...)"
else
log "Not logged in"
exit 1
fi
}

case "$1" in
login)
github_login
;;
logout)
logout
;;
whoami)
whoami
;;
*)
echo "Usage: $0 {login|logout|whoami}"
echo " login - Authenticate with GitHub"
echo " logout - Remove stored credentials"
echo " whoami - Show current login status"
exit 1
;;
esac
11 changes: 9 additions & 2 deletions setup-mac.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,15 @@ log() {
}

echo "Setting up Zsh prompt..."
touch ~/.zshrc
echo 'PS1="$ "' >> ~/.zshrc
if [ ! -f ~/.zshrc ]; then
touch ~/.zshrc
fi

# Only add PS1 if it doesn't already exist
if ! grep -q 'PS1=' ~/.zshrc; then
echo 'PS1="$ "' >> ~/.zshrc
fi

# shellcheck disable=SC1090
source ~/.zshrc

Expand Down
142 changes: 142 additions & 0 deletions sync/dotfiles-sync.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/bin/bash

# Dotfiles sync functionality (requires authentication)
AUTH_DIR="$HOME/.dotfiles"
TOKEN_FILE="$AUTH_DIR/token"
USER_FILE="$AUTH_DIR/user"
SYNC_REPO="dotfiles-sync"

log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1"
}

check_auth() {
if [ ! -f "$TOKEN_FILE" ] || [ ! -f "$USER_FILE" ]; then
log "ERROR: Not logged in. Run './auth/login.sh login' first"
exit 1
fi
}

sync_push() {
check_auth

USERNAME=$(cat "$USER_FILE")

log "Syncing dotfiles to GitHub..."

# Create backup of current dotfiles
BACKUP_DIR="/tmp/dotfiles-backup-$(date +%s)"
mkdir -p "$BACKUP_DIR"

# Copy key dotfiles
[ -f ~/.gitconfig ] && cp ~/.gitconfig "$BACKUP_DIR/"
[ -f ~/.zshrc ] && cp ~/.zshrc "$BACKUP_DIR/"
[ -f ~/.bashrc ] && cp ~/.bashrc "$BACKUP_DIR/"
[ -f ~/.vimrc ] && cp ~/.vimrc "$BACKUP_DIR/"

# Create or update sync repository
if ! gh repo view "$USERNAME/$SYNC_REPO" &>/dev/null; then
log "Creating sync repository..."
gh repo create "$SYNC_REPO" --private --description "Dotfiles sync backup"
fi

# Push to sync repo
cd "$BACKUP_DIR" || exit 1
git init
git add .
git commit -m "sync: backup dotfiles $(date)"
git remote add origin "https://github.com/$USERNAME/$SYNC_REPO.git"

echo "⚠️ WARNING: This will overwrite the remote sync repository."
echo "Continue? (y/N): "
read -r confirm
if [[ "$confirm" =~ ^[Yy]$ ]]; then
git push --force-with-lease -u origin main 2>/dev/null || git push -u origin main --force
else
log "Sync cancelled by user"
rm -rf "$BACKUP_DIR"
exit 1
fi

log "Dotfiles synced to github.com/$USERNAME/$SYNC_REPO"
rm -rf "$BACKUP_DIR"
}

sync_pull() {
check_auth

USERNAME=$(cat "$USER_FILE")

log "Restoring dotfiles from GitHub..."

# Clone sync repo
RESTORE_DIR="/tmp/dotfiles-restore-$(date +%s)"
if gh repo clone "$USERNAME/$SYNC_REPO" "$RESTORE_DIR"; then
cd "$RESTORE_DIR" || exit 1

# Backup existing files
[ -f ~/.gitconfig ] && cp ~/.gitconfig ~/.gitconfig.backup
[ -f ~/.zshrc ] && cp ~/.zshrc ~/.zshrc.backup
[ -f ~/.bashrc ] && cp ~/.bashrc ~/.bashrc.backup
[ -f ~/.vimrc ] && cp ~/.vimrc ~/.vimrc.backup

# Restore files
[ -f .gitconfig ] && cp .gitconfig ~/
[ -f .zshrc ] && cp .zshrc ~/
[ -f .bashrc ] && cp .bashrc ~/
[ -f .vimrc ] && cp .vimrc ~/

log "Dotfiles restored from sync repository"
rm -rf "$RESTORE_DIR"
else
log "ERROR: No sync repository found. Run 'sync push' first"
exit 1
fi
}

premium_tools() {
check_auth

USERNAME=$(cat "$USER_FILE")
log "Premium tools for $USERNAME:"
echo " ✓ Advanced linting with custom rules"
echo " ✓ Team configuration sharing"
echo " ✓ Automated backup scheduling"
echo " ✓ Cross-platform sync"
echo ""
echo "Note: Premium features are currently in development"
}

premium_enable() {
check_auth

log "Premium features are currently in development."
log "Available now: sync push/pull functionality"
log "Coming soon: Advanced linting, team sharing, automated backups"
}

case "$1" in
push)
sync_push
;;
pull)
sync_pull
;;
premium)
if [ "$2" = "enable" ]; then
premium_enable
else
premium_tools
fi
;;
*)
echo "Usage: $0 {push|pull|premium [enable]}"
echo " push - Backup dotfiles to GitHub"
echo " pull - Restore dotfiles from GitHub"
echo " premium - Show premium features"
echo " premium enable - Enable premium features"
echo ""
echo "Note: Requires authentication (./auth/login.sh login)"
exit 1
;;
esac