-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Complete overhaul with GitHub Classroom API and BubbleTea library int…
…egration
- Loading branch information
1 parent
d2af1df
commit fecb1ee
Showing
45 changed files
with
2,136 additions
and
1,105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,4 +21,6 @@ go.work | |
/vendor/ | ||
/Godeps/ | ||
|
||
.vscode/ | ||
.vscode/ | ||
.idea/ | ||
/claro |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
before: | ||
hooks: | ||
- go mod tidy | ||
|
||
builds: | ||
- env: | ||
- CGO_ENABLED=0 | ||
goos: | ||
- freebsd | ||
- linux | ||
- windows | ||
- darwin | ||
goarch: | ||
- amd64 | ||
- arm64 | ||
- arm | ||
- "386" | ||
goarm: | ||
- 6 | ||
- 7 | ||
ldflags: | ||
- -s -w | ||
- -X github.com/emersonmello/claro/cmd.Version={{.Version}} | ||
- -X github.com/emersonmello/claro/cmd.Commit={{.Commit}} | ||
- -X github.com/emersonmello/claro/cmd.Date={{.CommitDate}} | ||
|
||
archives: | ||
- format: binary | ||
name_template: "{{ .Os }}-{{ .Arch }}" | ||
checksum: | ||
name_template: "checksums.txt" | ||
snapshot: | ||
name_template: "{{ incpatch .Version }}-next" | ||
changelog: | ||
sort: asc | ||
filters: | ||
exclude: | ||
- "^docs:" | ||
- "^test:" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
MIT License | ||
|
||
Copyright (c) 2022 Emerson Ribeiro de Mello | ||
Copyright (c) 2022-2024 Emerson Ribeiro de Mello <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,145 +9,72 @@ | |
[![Go Report Card](https://goreportcard.com/badge/github.com/emersonmello/claro)](https://goreportcard.com/report/github.com/emersonmello/claro) | ||
[![Compiling](https://github.com/emersonmello/claro/actions/workflows/release.yaml/badge.svg)](https://github.com/emersonmello/claro/actions/workflows/release.yaml) | ||
[![Plataform](https://img.shields.io/badge/Download%20binaries%20for-Linux%20%7C%20macOS-lightgreen)](https://github.com/emersonmello/claro/releases/latest) | ||
# Overview | ||
|
||
**claro** (**cla**ss**ro**om) is a cli tool that offers a simple interface that allows the teacher to clone all student repositories at once for grading and then send grades at once to all these repositories. | ||
|
||
**claro** was inspired by the [Git-Gud-tool](https://github.com/NikolaiMagnussen/Git-Gud-tool) and it was created to make my life simpler as a teacher who relies on Github Classroom. It is suitable for scenarios where the teacher needs to manually grade each assignment and the Github Classroom autograding is not an option. | ||
|
||
**claro** relies on [Github's REST API](https://docs.github.com/en/rest) because currently Github Classroom does not offer an API and it has features that are not present in [Github Classroom Assistant](https://classroom.github.com/assistant). The best one: it is a [CLI](https://clig.dev) :heart:! | ||
|
||
# Overview | ||
|
||
**claro** provides: | ||
- mass clone of Github repositories | ||
- a template in Markdown for grading (it creates one file per repository) | ||
- customization (commit message, grade sheet title, grading file, etc.) | ||
- access to [Github Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) from operating system keyring (i.e. macOS Keychain, Gnome Keyring), environment var or claro's config file | ||
|
||
## Requirements | ||
- [git](https://git-scm.com/docs/git) command line application configured properly | ||
```bash | ||
git config --global user.email "[email protected]" | ||
git config --global user.name "Your Name" | ||
``` | ||
- [Git credential store](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage) configured properly | ||
- See [section below](#authenticating-with-git-command-line-to-access-repositories-on-github) | ||
**claro** (**cla**ss**ro**om) is a [CLI](https://clig.dev) tool designed to simplify the grading process for educators using [GitHub Classroom](classroom.github.com), especially in cases where manual grading is necessary and autograding is not an option. **claro** is an alternative to the [GitHub Classroom Assistant](https://classroom.github.com/assistant) and [Github CLI](https://cli.github.com), which currently lacks bulk processing features for grading. With claro, you can efficiently clone all student repositories, grade them, and push the grades back. | ||
|
||
**claro** offers: | ||
- Bulk cloning and pushing of student assignment repositories | ||
- Automatic generation of a Markdown grading template (one file per repository) | ||
- Customization options (commit messages, grade sheet titles, grading files, etc.) | ||
- Integration with [Github Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) via your operating system’s keyring (e.g., macOS Keychain, Gnome Keyring) | ||
|
||
## Usage | ||
![claro help message](images/claro.png) | ||
|
||
### Straight workflow | ||
## Straight workflow | ||
|
||
1. Create a Github Classroom assignment with a distinguish repository prefix | ||
- Example: `2022-01-assignment-01` | ||
2. Clone all repositories from a Github Classroom organization with a specific assignment prefix | ||
- Example: `claro clone github-organization 2022-01-assignment-01` | ||
1. Clone all repositories from a Github Classroom assignment | ||
- Example: `claro clone` | ||
|
||
![cloning](images/clone.gif) | ||
|
||
3. Grade each student's work and write down the feedback in the respective Markdown file | ||
2. Grade each student's work and write down the feedback in the respective Markdown file | ||
- Tip: Use your best Markdown editor for this | ||
|
||
![grading](images/grading.gif) | ||
|
||
4. Push the grading | ||
- Example: `claro push 2022-01-assignment-01` | ||
3. Upload student grades to GitHub | ||
- Example: `claro push <directory-with-student-submissions>` | ||
|
||
![pushing](images/push.gif) | ||
|
||
## Other commands | ||
## Additional commands | ||
|
||
![claro help message](images/claro.png) | ||
### Pulls the latest changes from all student repositories | ||
|
||
- Example: `claro pull <directory-with-student-submissions>` | ||
|
||
### Pull students repositories | ||
![pulling](images/pull.gif) | ||
|
||
**claro** offers a `pull` command suitable for workflows where students make incremental deliveries to the same GitHub Classroom repository. | ||
### Add a GitHub Personal Access Token to the operating system keyring | ||
|
||
- Example: | ||
```bash | ||
claro pull 2022-01-assignment-01 | ||
``` | ||
### List all repositories which start with a specific prefix | ||
- Example: `claro token add` | ||
|
||
Before cloning multiple repositories, you might want to check which repositories will be cloned with a specific prefix. **claro** offers the `list` command for that. | ||
### Remove a GitHub Personal Access Token from the operating system keyring | ||
|
||
- Example: | ||
```bash | ||
claro list 2022-01-assignment-01 | ||
``` | ||
- Example: `claro token del` | ||
|
||
### Customize commit message, grading filename, grading string | ||
|
||
You can customize the commit message, grading filename, and grading string using the `config` command. The new values will be stored in the **claro**'s config file (default `$HOME/.config/claro/config.env`). | ||
|
||
The **claro** default strings are: | ||
|
||
- **Grading filename:** `GRADING.md` | ||
- It will be created and pushed to student repository | ||
- **Grade string:** `Grade: ` | ||
- It will be inside grading file | ||
- **Commit message:** `Graded project, the file containing the grade is in the root directory` | ||
- **Commit message:** `This project has been graded. The file containing the grade is located in the root directory.` | ||
- It is the commit message | ||
- **Grade sheet title** `Feedback` | ||
- It will be inside grading file as title 1 (# Feedback) | ||
|
||
You can change the values using **claro** `config` command. The new values will be stored in the **claro**'s config file (default `$HOME/.claro.env`). | ||
- Examples: | ||
- `claro config filename "Correcao.md"` | ||
- `claro config grade "Nota: "` | ||
- `claro config message "Correção finalizada, veja arquivo na raiz do repositório"` | ||
- `claro config title "Comentários"` | ||
|
||
## Storing claro's GitHub Personal Access Token in the OS keyring | ||
|
||
**claro** only supports HTTPS remote URL (git over SSH is so [annoying](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#authenticating-with-the-command-line)). | ||
|
||
**claro** consumes [Github's REST API](https://docs.github.com/en/rest) to fetch the list of repositories (assignments) from a GitHub Classroom organization. So, **claro** uses a [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token). | ||
- **claro** will try to get GitHub Personal Access Token from: (1) operating system keyring; (2) environment var (`GH_TOKEN`); (3) **claro**'s config file (default `$HOME/.claro.env`) | ||
|
||
You can inform the token whenever you clone repositories, or you can save the token in the operating system keyring (recommended) or in the **claro**'s config file. Please, have a look at [Authenticating with git command line to access repositories on GitHub](#authenticating-with-git-command-line-to-access-repositories-on-github). | ||
|
||
- To save the token (**claro** will try to save to the OS keyring first and then to the config file.) | ||
- `claro config token add` | ||
- To delete the token from OS keyring | ||
- `claro config token del` | ||
|
||
## Authenticating with git command line to access repositories on GitHub | ||
|
||
|
||
|
||
> Using an HTTPS remote URL has some advantages compared with using SSH. It's easier to set up than SSH, and usually works through strict firewalls and proxies. However, it also prompts you to enter your GitHub credentials every time you pull or push a repository. ([GitHub Docs](https://docs.github.com/en/get-started/getting-started-with-git/why-is-git-always-asking-for-my-password)). | ||
To access repositories on GitHub from the command line application over HTTPS you must authenticate with a [GitHub personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#authenticating-with-the-command-line). | ||
|
||
You can avoid being prompted for your password (personal access token) by configuring Git to cache your credentials for you on [git credential storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage). Git works with several credential helper: | ||
|
||
- **Unsafe and simple way** (not recommended!) | ||
- This method stores your password in plaintext on disk, protected only by filesystem permissions (default `$HOME/.git-credentials`) | ||
- on Linux, macOS or Windows | ||
```bash | ||
git config --global credential.helper store | ||
``` | ||
- The first time git will ask the username and password. Subsequent request will use the credentials from the store (default `$HOME/.git-credentials`). | ||
- Example: | ||
`https://username:[email protected]` | ||
- **Safe with a little complexity** | ||
- This method stores your password encrypted on disk in the operating system keyring service. | ||
- You can use native operating system keyring | ||
- Linux [Secret Service](https://specifications.freedesktop.org/secret-service/latest/) dbus interface, which is provided by [GNOME Keyring](https://wiki.gnome.org/Projects/GnomeKeyring) | ||
- Use [Seahorse app](https://wiki.gnome.org/Apps/Seahorse) to create a default collection with `login` name | ||
- Open `seahorse`; go to `file->new->password keyring`; when asked for a name, use: `login` | ||
|
||
```bash | ||
# ------------------------------------------------# | ||
# on Ubuntu Linux 22.04 LTS | ||
# ------------------------------------------------# | ||
sudo apt-get install libsecret-1-0 libsecret-1-dev g++ make | ||
cd /usr/share/doc/git/contrib/credential/libsecret && sudo make | ||
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret | ||
# ------------------------------------------------# | ||
``` | ||
- macOS Keychain (`/usr/bin/security`) | ||
- `git config --global credential.helper osxkeychain` | ||
- Multi-plataform (Linux, macOS or Windows) | ||
- You can also use a credential helper like [Git Credential Manager](https://github.com/GitCredentialManager/git-credential-manager) | ||
![alt text](images/config.gif) | ||
|
||
|
||
## GitHub Personal Access Token | ||
|
||
**claro** uses Git to clone, pull, and push repositories. To streamline this process, **claro** will prompt you for your GitHub credentials each time you perform these actions. This can be tedious, especially when handling multiple repositories. To avoid repeated prompts, **claro** will check if [Git's credential storage](https://git-scm.com/book/en/v2/Git-Tools-Credential-Storage) is configured on its first run. If not, it will set up Git to store credentials in cache (e.g., `git config --global credential.helper cache`). You will be asked for your GitHub Personal Access Token only once, and it will remain cached until the cache expires. | ||
|
||
**claro** also requires a [GitHub Personal Access Token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) to access the [Github's Classroom API](https://docs.github.com/en/rest/classroom?apiVersion=2022-11-28) when cloning repositories. This token is not stored in Git's credential storage, so it is best kept in your operating system's keyring. You can store it using the token add command. Once saved, you won’t need to re-enter it each time you use **claro**. For instructions on how to use your operating system's keyring, [see this guide](https://git-scm.com/doc/credential-helpers). |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Package clone | ||
package clone | ||
|
||
/* | ||
Copyright © 2022-2024 Emerson Ribeiro de Mello <[email protected]> | ||
*/ | ||
|
||
import ( | ||
"fmt" | ||
|
||
tea "github.com/charmbracelet/bubbletea" | ||
"github.com/emersonmello/claro/internal" | ||
"github.com/emersonmello/claro/internal/tui" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// Clone represents the clone command | ||
func Clone() *cobra.Command { | ||
cloneCmd := &cobra.Command{ | ||
Use: "clone", | ||
Short: "Clone all students assignments from a GitHub Classroom", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
if !tui.GitHubCliInstalled { | ||
tui.UserGitHubPAT = internal.GetAndSaveToken() | ||
} | ||
if _, err := tea.NewProgram(internal.NewCloneModel()).Run(); err != nil { | ||
fmt.Println("Error running program:", err) | ||
} | ||
return nil | ||
}, | ||
} | ||
return cloneCmd | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Package config | ||
package config | ||
|
||
/* | ||
Copyright © 2022-2024 Emerson Ribeiro de Mello <[email protected]> | ||
*/ | ||
|
||
import ( | ||
"github.com/emersonmello/claro/internal" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// Config represents the clone command | ||
func Config() *cobra.Command { | ||
configCmd := &cobra.Command{ | ||
Use: "config", | ||
Short: "Configure claro's properties (commit message, filename, etc)", | ||
RunE: internal.ConfigCmd, | ||
} | ||
return configCmd | ||
} |
Oops, something went wrong.