Skip to content

Commit

Permalink
Merge PR #37.
Browse files Browse the repository at this point in the history
  • Loading branch information
dainnilsson committed Nov 24, 2023
2 parents efc896c + 956257b commit 2b7e6d9
Show file tree
Hide file tree
Showing 14 changed files with 202 additions and 207 deletions.
144 changes: 87 additions & 57 deletions gitbark/cli/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from gitbark.commands.verify import verify as verify_cmd
from gitbark.commands.install import is_installed, install as install_cmd
from gitbark.commands.verify import (
verify_all,
verify_ref,
verify_commit,
verify_ref_update,
)
from gitbark.commands.install import install as install_cmd
from gitbark.commands.setup import (
setup as setup_cmd,
add_modules_interactive,
Expand All @@ -23,11 +28,11 @@
checkout_or_orphan,
)

from gitbark.core import BARK_RULES_BRANCH
from gitbark.core import BARK_RULES_REF
from gitbark.project import Project
from gitbark.rule import RuleViolation
from gitbark.util import cmd, branch_name
from gitbark.git import Commit, ReferenceUpdate
from gitbark.util import cmd
from gitbark.git import Commit, BRANCH_REF_PREFIX, TAG_REF_PREFIX
from .util import (
BarkContextObject,
click_callback,
Expand All @@ -45,6 +50,35 @@
logger = logging.getLogger(__name__)


def ensure_bootstrap_verified(project: Project) -> None:
root_hash = cmd("git", "rev-list", "--max-parents=0", BARK_RULES_REF)[0]
root = Commit(bytes.fromhex(root_hash), project.repo)
if project.bootstrap:
if project.bootstrap != root:
raise CliFail(
"WARNING! The previously trusted bootstrap commit has CHANGED!"
)
else:
click.echo(
f"The bootstrap commit ({root_hash}) of the bark_rules "
"branch has not been verified!"
)
click.confirm(
"Do you want to trust this commit as the bootstrap for bark?",
abort=True,
err=True,
)
project.bootstrap = root


def format_ref(ref: str) -> str:
if ref.startswith(BRANCH_REF_PREFIX):
return f"branch {ref[len(BRANCH_REF_PREFIX) :]}"
if ref.startswith(TAG_REF_PREFIX):
return f"tag {ref[len(TAG_REF_PREFIX) :]}"
return ref


@click.group()
@click.pass_context
def cli(ctx):
Expand Down Expand Up @@ -132,22 +166,10 @@ def install(ctx):
project = ctx.obj["project"]

repo = project.repo
if BARK_RULES_BRANCH not in repo.branches:
if BARK_RULES_REF not in repo.references:
raise CliFail('The "bark_rules" branch has not been created!')

root_commit_hash = cmd("git", "rev-list", "--max-parents=0", BARK_RULES_BRANCH)[0]
root_commit = Commit(bytes.fromhex(root_commit_hash), repo)
if root_commit != project.bootstrap:
click.echo(
f"The bootstrap commit ({root_commit.hash.hex()}) of the branch_rules "
"branch has not been verified!"
)
click.confirm(
"Do you want to trust this commit as the bootstrap commit?",
abort=True,
err=True,
)
project.bootstrap = root_commit
ensure_bootstrap_verified(project)

try:
install_cmd(project)
Expand All @@ -167,10 +189,37 @@ def click_parse_bootstrap(ctx, param, val):
return None


@click_callback()
def click_parse_ref_update(ctx, param, val):
old_ref, new_ref, ref_name = val
return ReferenceUpdate(old_ref, new_ref, ref_name)
@cli.command(hidden=True)
@click.pass_context
@click.argument("old")
@click.argument("new")
@click.argument("ref")
def ref_update(ctx, old, new, ref):
"""Verify ref update"""
project = ctx.obj["project"]

if old == new or ref not in project.repo.references:
# Not a change of a "real" ref
return

if new == "00" * 20:
# Ref deletion
return

head = Commit(bytes.fromhex(new), project.repo)
fail_head = os.path.join(project.bark_directory, "FAIL_HEAD")
try:
verify_ref_update(project, ref, head)
if os.path.exists(fail_head):
os.remove(fail_head)
except RuleViolation as e:
with open(fail_head, "w") as f:
f.write(head.hash.hex())
# TODO: Error message here?
pp_violation(e)
sys.exit(1)
finally:
project.update()


@cli.command()
Expand All @@ -182,7 +231,7 @@ def click_parse_ref_update(ctx, param, val):
is_flag=True,
show_default=True,
default=False,
help="Verify all branches.",
help="Verify all refs.",
)
@click.option(
"-b",
Expand All @@ -191,53 +240,34 @@ def click_parse_ref_update(ctx, param, val):
help="Verify from bootstrap",
callback=click_parse_bootstrap,
)
@click.option(
"-r",
"--ref-update",
type=(str, str, str),
hidden=True,
callback=click_parse_ref_update,
)
def verify(ctx, target, all, bootstrap, ref_update):
def verify(ctx, target, all, bootstrap):
"""
Verify repository or branch.
Verify repository or ref.
\b
TARGET the commit or branch to verify.
TARGET the commit or ref to verify.
"""

project = ctx.obj["project"]
if not is_installed(project):
raise CliFail("Bark is not installed! Run 'bark install' first!")

if ref_update:
if ref_update.ref_name not in project.repo.references:
return
ref = ref_update.ref_name
head = Commit(bytes.fromhex(ref_update.new_ref), project.repo)
else:
head, ref = project.repo.resolve(target)
if not ref and not bootstrap:
raise CliFail(
"verifying a single commit requires specifying a bootstrap with -b"
)
ensure_bootstrap_verified(project)

fail_head = os.path.join(project.bark_directory, "FAIL_HEAD")
try:
verify_cmd(project, ref, head, bootstrap, all)
if all:
verify_all(project)
click.echo("Repository is in valid state!")
elif not ref_update:
else:
head, ref = project.repo.resolve(target)
if ref:
click.echo(f"Branch {branch_name(ref)} is in a valid state!")
verify_ref(project, ref, head)
click.echo(f"{format_ref(ref)} is in a valid state!")
elif not bootstrap:
raise CliFail(
"verifying a single commit requires specifying a bootstrap with -b"
)
else:
verify_commit(project, head, bootstrap)
click.echo(f"Commit {head.hash.hex()} is in a valid state!")
if os.path.exists(fail_head):
os.remove(fail_head)
except RuleViolation as e:
if ref_update:
with open(fail_head, "w") as f:
f.write(head.hash.hex())
# TODO: Error message here?
pp_violation(e)
sys.exit(1)
Expand Down
4 changes: 2 additions & 2 deletions gitbark/commands/hooks/reference_transaction
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ if [ "$1" == "prepared" ]; then
done

if ! [ "$ref_update" == "" ]; then
bark verify -r $ref_update
bark ref-update $ref_update
exit_status=$(echo $?)
if [ $exit_status -ne 0 ]; then
exit 1
fi
fi
fi
fi
22 changes: 0 additions & 22 deletions gitbark/commands/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from .verify import verify
from ..project import Project
from ..util import cmd
from ..core import BARK_RULES_REF

import pkg_resources
import os
Expand All @@ -26,29 +23,10 @@ def install(project: Project) -> None:
"""
Installs GitBark
"""
# Verify the branch rules branch
verify(project, all=True)

# If everything goes well, install hooks
if not hooks_installed(project):
install_hooks(project)


def bootstrap_verified(project: Project) -> bool:
bootstrap = project.bootstrap
if bootstrap:
try:
root_commit = cmd("git", "rev-list", "--max-parents=0", BARK_RULES_REF)[0]
return root_commit == bootstrap.hash.hex()
except Exception:
pass # Fall through
return False


def is_installed(project: Project) -> bool:
return bootstrap_verified(project) and hooks_installed(project)


def install_hooks(project: Project):
print("Installing hooks....")
reference_transaction_data = pkg_resources.resource_string(
Expand Down
22 changes: 17 additions & 5 deletions gitbark/commands/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
BARK_REQUIREMENTS,
)
from ..objects import BarkRules, RuleData
from ..git import Commit, COMMIT_RULES, BARK_CONFIG
from ..git import Commit, COMMIT_RULES, BARK_CONFIG, BRANCH_REF_PREFIX
from ..project import Project
from ..util import cmd, BRANCH_REF_PREFIX
from ..util import cmd

from ..cli.util import click_prompt, CliFail

Expand Down Expand Up @@ -173,7 +173,7 @@ def add_rules_interactive(ep_group: str, rules: list) -> None:
if not choices:
raise CliFail("No configurable rules. Provide configuration manually.")

while True:
while choices:
newline()
click.echo("Choose rule (leave blank to skip):")
max_length_rule_name = max(len(name) for (name, _) in choices.values())
Expand All @@ -194,11 +194,12 @@ def add_rules_interactive(ep_group: str, rules: list) -> None:
if not choice:
break

rule_id, rule = choices[int(choice)]
click.echo(f"Configure the {rule_id} rule!")
rule_id, rule = choices.pop(int(choice))
click.echo(f"Adding rule: {rule_id}")
newline()

rules.append(rule.setup())
click.echo(f"Successfully added rule: {rule_id}")


def add_commit_rules_interactive(project: Project) -> None:
Expand Down Expand Up @@ -310,6 +311,17 @@ def setup(project: Project) -> None:
newline()
add_commit_rules_interactive(project)

rules = add_branch_rules_interactive(BARK_RULES_BRANCH)
bark_rules = get_bark_rules(project)
bark_rules.bark_rules = rules
_confirm_bark_rules(bark_rules)

dump_and_stage(
project=project,
file=f"{project.path}/{BARK_RULES}",
content=yaml.safe_dump(asdict(bark_rules), sort_keys=False),
)

_confirm_commit(commit_message="Add initial modules and rules (made by bark).")

active_branch = get_active_branch(project)
Expand Down
Loading

0 comments on commit 2b7e6d9

Please sign in to comment.