Skip to content

Commit

Permalink
add initial version of command-line tool gsctl. (#2868)
Browse files Browse the repository at this point in the history
<!--
copilot:summary
-->
### <samp>🤖 Generated by Copilot at f6e1599</samp>

This pull request introduces a new command-line utility for GraphScope,
`gsutil.py`, which can perform various tasks such as installing
dependencies, building components, making docker images, and triggering
tests. It also adds the `click` package as a dependency in
`requirements.txt` to support the utility.


to issue #2825
  • Loading branch information
yecol committed Jun 13, 2023
1 parent 7a3e06b commit 4af5689
Show file tree
Hide file tree
Showing 5 changed files with 255 additions and 1 deletion.
32 changes: 31 additions & 1 deletion docs/utilities/gs.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,33 @@
# Command-line Utility `gs`
# Command-line Utility `gsctl`

`gsctl` is a command-line utility for GraphScope. It is shipped with `graphscope-client` and provides a set of functionalities to make it easy to use GraphScope. These functionalities include building and testing binaries, managing sessions and resources, and more.

## Install/Update `gsctl`

Since it is shipped with python package `graphscope-client`, the `gsctl` command will be available in your terminal after installing GraphScope:
```bash
pip install graphscope-client
```

In some cases, such as development on `gsctl`, you may want to build it from source.
To do this, navigate to the directory where the source code is located and run the following command:

```bash
cd REPO_HOME/python
# If you want to develop gsctl,
# please note the entry point is located on:
# /python/graphscope/gsctl/gsctl.py
pip install --editable .
```
This will install `gsctl` in an editable mode, which means that any changes you make to the source code will be reflected in the installed version of `gsctl`.

## Commands

With `gsctl`, you can do the following things. Always remember to
use `--help` on a command to get more information.

- `gsctl install-deps`, install dependencies for building GraphScope.
- `gsctl make`, build GraphScope executable binaries and artifacts.
- `gsctl make-image`, build GraphScope docker images.
- `gsctl test`, trigger test suites.

218 changes: 218 additions & 0 deletions python/graphscope/gsctl/gsctl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2023 Alibaba Group Holding Limited. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import io
import os
import subprocess

import click


def run_shell_cmd(cmd, workingdir):
"""wrapper function to run a shell command/scripts."""
click.echo(f"run a shell command on cwd={workingdir}. \ncmd=\"{' '.join(cmd)}\"")
proc = subprocess.Popen(cmd, cwd=workingdir, stdout=subprocess.PIPE)
for line in io.TextIOWrapper(proc.stdout, encoding="utf-8"):
print(line.rstrip())


class GSCtl(object):
"""GraphScope command-line utility
This is a context for the utility.
"""

def __init__(self, repo_home=None, debug=False):
self.home = os.path.abspath("../")
self.debug = debug


@click.group()
@click.option(
"--repo-home",
envvar="REPO_HOME",
type=click.Path(),
help="GraphScope code repo location.",
)
@click.pass_context
def cli(ctx, repo_home):
ctx.obj = GSCtl(repo_home)


@click.command()
@click.pass_obj
def install_deps():
"""Install dependencies for building GraphScope."""
click.echo("install_deps")


@click.command()
@click.argument(
"component",
type=click.Choice(
["interactive", "analytical", "learning", "coordinator", "client"],
case_sensitive=False,
),
required=False,
)
@click.option(
"--clean",
is_flag=True,
default=False,
help="Flag indicating whether clean previous build.",
)
@click.option(
"--install",
is_flag=True,
default=False,
help="Flag indicating whether install after built binaries.",
)
@click.option(
"--install-prefix",
type=click.Path(),
default="/opt/graphscope",
show_default=True,
help="Install built binaries to customized location.",
)
@click.option(
"--with-java",
is_flag=True,
default=False,
help="Whether build analytical engine with Java support.",
)
@click.option(
"--storage-type",
type=click.Choice(["experimental", "vineyard"], case_sensitive=False),
help="Make gie with specified storage type.",
)
@click.pass_obj
def make(repo, component, clean, install, install_prefix, storage_type, with_java):
"""Build executive binaries of COMPONENT. If not given a specific component, build all.
\f
TODO: maybe without make?
"""
if clean:
click.secho("Cleaning previous build.", fg="green")
cmd = ["make", "clean"]
run_shell_cmd(cmd, repo.home)
return
click.secho(
"Before making artifacts, please manually source ENVs from ~/.graphscope_env.",
fg="yellow",
)
click.secho(
f"Begin the make command, to build components [{component}] of GraphScope, with repo = {repo.home}",
fg="green",
)
cmd = []
workingdir = repo.home
if component == "interactive":
click.secho("Building interactive engine.", fg="green")
if storage_type == "experimental":
cmd = ["make", "build", 'QUIET_OPT=""']
workingdir = os.path.join(repo.home, "interactive_engine", "compiler")
if storage_type == "vineyard":
cmd = [
"mvn",
"install",
"-DskipTests",
"-Drust.compile.mode=release",
"-P",
"graphscope,graphscope-assembly",
]
workingdir = os.path.join(repo.home, "interactive_engine")
run_shell_cmd(cmd, workingdir)
cmd = ["tar", "xvzf", "graphscope.tar.gz"]
workingdir = os.path.join(
repo.home, "interactive_engine", "assembly", "target"
)
click.secho(f"Begin to extract, from {workingdir}.", fg="green")
run_shell_cmd(cmd, workingdir)
click.secho("GraphScope interactive engine has been built.", fg="green")
if install is True:
cmd = [
"make",
"interactive-install",
"INSTALL_PREFIX={}".format(install_prefix),
]
run_shell_cmd(cmd, repo.home)
click.secho(
f"GraphScope interactive engine has been installed to {install_prefix}.",
fg="green",
)

if component == "analytical":
cmd = ["make", "analytical"]
if with_java:
cmd = ["make", "analytical-java"]
run_shell_cmd(cmd, repo.home)
click.secho("GraphScope analytical engine has been built.", fg="green")
if install is True:
cmd = [
"make",
"analytical-install",
"INSTALL_PREFIX={}".format(install_prefix),
]
run_shell_cmd(cmd, repo.home)
click.secho(
f"GraphScope analytical engine has been installed to {install_prefix}.",
fg="green",
)

if component == "client":
cmd = ["make", "client"]
run_shell_cmd(cmd, repo.home)

if component == "coordinator":
cmd = ["make", "coordinator"]
run_shell_cmd(cmd, repo.home)

if component is None:
click.secho("Building all components.", fg="green")
cmd = ["make", "all"]
if install is True:
cmd = ["make", "install", "INSTALL_PREFIX={}".format(install_prefix)]
run_shell_cmd(cmd, repo.home)


@click.command()
def make_image():
"""Make docker images from source code for deployment.
\f
TODO: fulfill this.
"""
click.echo("make_image")


@click.command()
@click.pass_obj
def test(repo):
"""Trigger tests on built artifacts.
\f
TODO: fulfill this."""
click.secho(f"repo.home = {repo.home}", fg="green")
click.echo("test")


cli.add_command(install_deps)
cli.add_command(make)
cli.add_command(make_image)
cli.add_command(test)
Empty file.
1 change: 1 addition & 0 deletions python/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ujson;python_version>="3.11"
PyYAML
rich
tqdm
click
vineyard>=0.15.0;sys_platform!="win32"
vineyard-io>=0.15.0;sys_platform!="win32"

5 changes: 5 additions & 0 deletions python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,11 @@ def parse_version(root, **kwargs):
"Source": "https://github.com/alibaba/GraphScope",
"Tracker": "https://github.com/alibaba/GraphScope/issues",
},
entry_points={
"console_scripts": [
"gsctl = graphscope.gsctl.gsctl:cli",
],
},
)

if os.name == "nt":
Expand Down

0 comments on commit 4af5689

Please sign in to comment.