Skip to content

Git lint #1

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 24 commits into
base: CI
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e995e52
dropbox_share bot: Pin dropbox version to 10.10.0.
LoopThrough-i-j Jan 8, 2021
9ce2ea5
integrations: Remove !avatar from game handler.
ahmedabuamra Feb 5, 2021
3e28506
zulip-apis: Update `reaction_data` type.
LoopThrough-i-j Feb 23, 2021
6337eca
CI: Setup CI with Github Actions replacing Travis.
LoopThrough-i-j Feb 3, 2021
ca4f6e5
CI: Add gh-action badge and remove travis badge.
LoopThrough-i-j Feb 3, 2021
f100dba
editorconfig: Adjust to 2-space indents for yaml.
alexmv Feb 23, 2021
424404d
README: Fix extra space in Markdown link.
alexmv Feb 23, 2021
4c75057
dropbox-bot: Update to support dropbox>=11.0.0.
LoopThrough-i-j Feb 24, 2021
6ac2165
provision: Replace virtualenv with python native venv.
LoopThrough-i-j Feb 25, 2021
3887ad1
python-zulip-api: Drop python3.5 support.
LoopThrough-i-j Feb 26, 2021
889e5e3
zulip-bots: Add `BotStorage` Protocol.
LoopThrough-i-j Mar 3, 2021
a994c58
zulip-bots: Add `BotHandler` Protocol.
LoopThrough-i-j Mar 3, 2021
1fb3d52
zulip-bots: Set `bot_handler` type to `BotHandler`.
LoopThrough-i-j Mar 3, 2021
f56f824
zulip-bots: Replace `ExternalBotHandler` type by `BotHandler`.
LoopThrough-i-j Mar 3, 2021
5f1590f
requirements: Upgrade zulint and mypy.
ganpa3 Mar 2, 2021
44b6fd3
tests: Fix tests failing on Windows.
ganpa3 Mar 2, 2021
f8cd424
docs: Add set and fetch upstream.
LoopThrough-i-j Feb 25, 2021
cce18ed
lint: Setup gitlint.
LoopThrough-i-j Feb 25, 2021
c4a78d0
lint: Remove gitlint from static analysis.
LoopThrough-i-j Feb 25, 2021
2e3c65a
lint: Remove custom --no-gitlint option.
andersk Mar 4, 2021
922446d
test-static-analysis: Delete.
andersk Mar 4, 2021
edcb894
requirements: Upgrade mypy from 0.790 to 0.812.
andersk Mar 4, 2021
5b5fda2
Fix % formatting without a tuple.
andersk Mar 4, 2021
2b81681
lint: Set repository variable in tools/lint-commits.
LoopThrough-i-j May 6, 2021
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
4 changes: 2 additions & 2 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.{sh,py,pyi,js,json,yml,xml,css,md,markdown,handlebars,html}]
[*.{sh,py,pyi,js,json,xml,css,md,markdown,handlebars,html}]
indent_style = space
indent_size = 4

[*.{svg,rb,pp,pl}]
[*.{svg,rb,pp,pl,yaml,yml}]
indent_style = space
indent_size = 2

Expand Down
61 changes: 61 additions & 0 deletions .github/workflows/zulip-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: build

on:
push:
branches:
- master
pull_request:

jobs:
static-analysis:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Setup Python 3.6
uses: actions/setup-python@v2
with:
python-version: 3.6

- name: Install dependencies
run: |
sudo rm -vf /etc/apt/sources.list.d/*
sudo apt-get update
sudo apt-get install virtualenv
tools/provision --force

- name: Running Test-Suite
run: |
source zulip-api-py3-venv/bin/activate
tools/lint --skip=gitlint

test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [3.6, 3.7, 3.8, 3.9]

steps:
- uses: actions/checkout@v2

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
sudo rm -vf /etc/apt/sources.list.d/*
sudo apt-get update
sudo apt-get install virtualenv
tools/provision --force

- name: Running Test-Suite
run: |
source zulip-api-py3-venv/bin/activate
tools/test-main

- name: Codecov
uses: codecov/[email protected]
15 changes: 15 additions & 0 deletions .gitlint
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This file is copied from the original .gitlint at zulip/zulip.
# Please don't edit here; instead update the zulip/zulip copy and then resync this file.

[general]
ignore=title-trailing-punctuation, body-min-length, body-is-missing
extra-path=tools/gitlint-rules.py

[title-match-regex]
regex=^(.+:\ )?[A-Z].+\.$

[title-max-length]
line-length=76

[body-max-line-length]
line-length=76
24 changes: 0 additions & 24 deletions .travis.yml

This file was deleted.

25 changes: 13 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Zulip API

[![Build status](https://travis-ci.com/zulip/python-zulip-api.svg?branch=master)](https://travis-ci.com/github/zulip/python-zulip-api)
[![Build status](https://github.com/zulip/python-zulip-api/workflows/build/badge.svg?branch=master)](
https://github.com/zulip/python-zulip-api/actions?query=branch%3Amaster+workflow%3Abuild)
[![Coverage status](https://img.shields.io/codecov/c/github/zulip/python-zulip-api/master.svg)](
https://codecov.io/gh/zulip/python-zulip-api)

Expand All @@ -21,17 +22,17 @@ This is part of the Zulip open source project; see the
[contributing guide](https://zulip.readthedocs.io/en/latest/overview/contributing.html)
and [commit guidelines](https://zulip.readthedocs.io/en/latest/contributing/version-control.html).

1. Fork and clone the Git repo:
`git clone https://github.com/<your_username>/python-zulip-api.git`

2. Make sure you have [pip](https://pip.pypa.io/en/stable/installing/)
and [virtualenv](https://virtualenv.pypa.io/en/stable/installation.html)
installed.
1. Fork and clone the Git repo, and set upstream to zulip/python-zulip-api:
```
git clone https://github.com/<your_username>/python-zulip-api.git
cd python-zulip-api
git remote add upstream https://github.com/zulip/python-zulip-api.git
git fetch upstream
```

3. `cd` into the repository cloned earlier:
`cd python-zulip-api`
2. Make sure you have [pip](https://pip.pypa.io/en/stable/installing/).

4. Run:
3. Run:
```
python3 ./tools/provision
```
Expand All @@ -42,14 +43,14 @@ and [commit guidelines](https://zulip.readthedocs.io/en/latest/contributing/vers
python3 ./tools/provision -p <path_to_your_python_version>
```

5. If that succeeds, it will end with printing the following command:
4. If that succeeds, it will end with printing the following command:
```
source /.../python-zulip-api/.../activate
```
You can run this command to enter the virtual environment.
You'll want to run this in each new shell before running commands from `python-zulip-api`.

6. Once you've entered the virtualenv, you should see something like this on the terminal:
5. Once you've entered the virtualenv, you should see something like this on the terminal:
```
(zulip-api-py3-venv) user@pc ~/python-zulip-api $
```
Expand Down
5 changes: 3 additions & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ pytest
-e ./zulip
-e ./zulip_bots
-e ./zulip_botserver
-e git+https://github.com/zulip/zulint@639c0d34c23ac559ef0f7b9510cf95f73f6d0eb9#egg=zulint==1.0.0
mypy==0.770
-e git+https://github.com/zulip/zulint@14e3974001bf8442a6a3486125865660f1f2eb68#egg=zulint==1.0.0
mypy==0.812
gitlint>=0.13.0
145 changes: 145 additions & 0 deletions tools/gitlint-rules.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# This file is copied from the original at tools/lib/gitlint-rules.py in zulip/zulip.
# Please don't edit here; instead update the zulip/zulip copy and then resync this file.

from typing import List

from gitlint.git import GitCommit
from gitlint.rules import CommitMessageTitle, LineRule, RuleViolation

# Word list from https://github.com/m1foley/fit-commit
# Copyright (c) 2015 Mike Foley
# License: MIT
# Ref: fit_commit/validators/tense.rb
WORD_SET = {
'adds', 'adding', 'added',
'allows', 'allowing', 'allowed',
'amends', 'amending', 'amended',
'bumps', 'bumping', 'bumped',
'calculates', 'calculating', 'calculated',
'changes', 'changing', 'changed',
'cleans', 'cleaning', 'cleaned',
'commits', 'committing', 'committed',
'corrects', 'correcting', 'corrected',
'creates', 'creating', 'created',
'darkens', 'darkening', 'darkened',
'disables', 'disabling', 'disabled',
'displays', 'displaying', 'displayed',
'documents', 'documenting', 'documented',
'drys', 'drying', 'dryed',
'ends', 'ending', 'ended',
'enforces', 'enforcing', 'enforced',
'enqueues', 'enqueuing', 'enqueued',
'extracts', 'extracting', 'extracted',
'finishes', 'finishing', 'finished',
'fixes', 'fixing', 'fixed',
'formats', 'formatting', 'formatted',
'guards', 'guarding', 'guarded',
'handles', 'handling', 'handled',
'hides', 'hiding', 'hid',
'increases', 'increasing', 'increased',
'ignores', 'ignoring', 'ignored',
'implements', 'implementing', 'implemented',
'improves', 'improving', 'improved',
'keeps', 'keeping', 'kept',
'kills', 'killing', 'killed',
'makes', 'making', 'made',
'merges', 'merging', 'merged',
'moves', 'moving', 'moved',
'permits', 'permitting', 'permitted',
'prevents', 'preventing', 'prevented',
'pushes', 'pushing', 'pushed',
'rebases', 'rebasing', 'rebased',
'refactors', 'refactoring', 'refactored',
'removes', 'removing', 'removed',
'renames', 'renaming', 'renamed',
'reorders', 'reordering', 'reordered',
'replaces', 'replacing', 'replaced',
'requires', 'requiring', 'required',
'restores', 'restoring', 'restored',
'sends', 'sending', 'sent',
'sets', 'setting',
'separates', 'separating', 'separated',
'shows', 'showing', 'showed',
'simplifies', 'simplifying', 'simplified',
'skips', 'skipping', 'skipped',
'sorts', 'sorting',
'speeds', 'speeding', 'sped',
'starts', 'starting', 'started',
'supports', 'supporting', 'supported',
'takes', 'taking', 'took',
'testing', 'tested', # 'tests' excluded to reduce false negative
'truncates', 'truncating', 'truncated',
'updates', 'updating', 'updated',
'uses', 'using', 'used',
}

imperative_forms = [
'add', 'allow', 'amend', 'bump', 'calculate', 'change', 'clean', 'commit',
'correct', 'create', 'darken', 'disable', 'display', 'document', 'dry',
'end', 'enforce', 'enqueue', 'extract', 'finish', 'fix', 'format', 'guard',
'handle', 'hide', 'ignore', 'implement', 'improve', 'increase', 'keep',
'kill', 'make', 'merge', 'move', 'permit', 'prevent', 'push', 'rebase',
'refactor', 'remove', 'rename', 'reorder', 'replace', 'require', 'restore',
'send', 'separate', 'set', 'show', 'simplify', 'skip', 'sort', 'speed',
'start', 'support', 'take', 'test', 'truncate', 'update', 'use',
]
imperative_forms.sort()


def head_binary_search(key: str, words: List[str]) -> str:
""" Find the imperative mood version of `word` by looking at the first
3 characters. """

# Edge case: 'disable' and 'display' have the same 3 starting letters.
if key in ['displays', 'displaying', 'displayed']:
return 'display'

lower = 0
upper = len(words) - 1

while True:
if lower > upper:
# Should not happen
raise Exception(f"Cannot find imperative mood of {key}")

mid = (lower + upper) // 2
imperative_form = words[mid]

if key[:3] == imperative_form[:3]:
return imperative_form
elif key < imperative_form:
upper = mid - 1
elif key > imperative_form:
lower = mid + 1


class ImperativeMood(LineRule):
""" This rule will enforce that the commit message title uses imperative
mood. This is done by checking if the first word is in `WORD_SET`, if so
show the word in the correct mood. """

name = "title-imperative-mood"
id = "Z1"
target = CommitMessageTitle

error_msg = ('The first word in commit title should be in imperative mood '
'("{word}" -> "{imperative}"): "{title}"')

def validate(self, line: str, commit: GitCommit) -> List[RuleViolation]:
violations = []

# Ignore the section tag (ie `<section tag>: <message body>.`)
words = line.split(': ', 1)[-1].split()
first_word = words[0].lower()

if first_word in WORD_SET:
imperative = head_binary_search(first_word, imperative_forms)
violation = RuleViolation(self.id, self.error_msg.format(
word=first_word,
imperative=imperative,
title=commit.message.title,
))

violations.append(violation)

return violations
5 changes: 4 additions & 1 deletion tools/lint
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#! /usr/bin/env python3

import argparse
import sys

from zulint.command import add_default_linter_arguments, LinterConfig

Expand All @@ -21,10 +22,12 @@ def run() -> None:
by_lang = linter_config.list_files(file_types=['py', 'sh', 'json', 'md', 'txt'],
exclude=EXCLUDED_FILES)

linter_config.external_linter('mypy', ['tools/run-mypy'], ['py'], pass_targets=False,
linter_config.external_linter('mypy', [sys.executable, 'tools/run-mypy'], ['py'], pass_targets=False,
description="Static type checker for Python (config: mypy.ini)")
linter_config.external_linter('flake8', ['flake8'], ['py'],
description="Standard Python linter (config: .flake8)")
linter_config.external_linter('gitlint', ['tools/lint-commits'],
description="Git Lint for commit messages")

@linter_config.lint
def custom_py() -> int:
Expand Down
29 changes: 29 additions & 0 deletions tools/lint-commits
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash

# This file is copied from the original tools/commit-message-lint at zulip/zulip,
# Edited at Line 14 Col 97 (zulip -> python-zulip-api)
# Please don't edit here; instead update the zulip/zulip copy and then resync this file.

# Lint all commit messages that are newer than upstream/master if running
# locally or the commits in the push or PR Gh-Actions.

# The rules can be found in /.gitlint

repository="zulip/python-zulip-api"

if [[ "
$(git remote -v)
" =~ '
'([^[:space:]]*)[[:space:]]*(https://github\.com/|ssh://git@github\.com/|git@github\.com:)"$repository"(\.git|/)?\ \(fetch\)'
' ]]; then
range="${BASH_REMATCH[1]}/master..HEAD"
else
range="upstream/master..HEAD"
fi

commits=$(git log "$range" | wc -l)
if [ "$commits" -gt 0 ]; then
# Only run gitlint with non-empty commit lists, to avoid a printed
# warning.
gitlint --commits "$range"
fi
Loading