nubsbizgolf

一个与Docker交互的库,用于执行用户的代码高尔夫提交并验证其正确性。

dev-master 2016-02-06 17:35 UTC

This package is auto-updated.

Last update: 2024-09-12 21:45:45 UTC


README

一个与Docker交互的库,用于执行用户的代码高尔夫提交并验证其正确性。

什么是代码高尔夫?

代码高尔夫是一种编程竞赛,目的是使用最少的代码字节数来解决编程问题。这测试了程序员的逻辑技能以及他们在语法所有角落案例中的编程语言知识。

什么是BizGolf?

Bizgolf是创建一个开源代码高尔夫库和托管平台,用于举办独立的代码高尔夫活动的尝试。

活动想法

  • 每年举行一次代码高尔夫锦标赛,每次只有一个活跃的洞。
  • 在两个或多个开发团队之间进行比赛。
  • 在黑客马拉松期间,可能还有一边的持续代码高尔夫锦标赛。

支持的语言

目前,只有PHP可用,但添加其他语言不应该太难。难点在于锁定语言功能,如shell执行、网络访问等,这可能会导致“作弊”。

包含的洞

将随着这个库的增长而包含一个不断增长的洞列表,使得尝试和运行即兴活动变得容易。虽然添加自己的洞也很简单。

要求

主机库目前是用PHP编写的,但它是一个可以轻松移植到另一种语言的库。它使用了一些php 5.4的功能,所以请确保您正在运行至少5.4。

使用Composer拉取所需的库。如果您使用Composer安装库并使用其自动加载器,它们将自动安装。

为了执行用户代码,使用Docker。它有一些严格的要求,但人们已经在许多环境中使其工作,并且有持续的努力使其能够在更多环境中工作。请查看其文档以了解如何在您的系统上安装它。

不需要其他要求,Docker负责为每种语言设置执行环境。

库使用

预期通过包含的PHP函数使用此库。通过composer将此库添加到您的PHP项目中

{
    "require": {
        "nubs/bizgolf": "dev-master"
    }
}

Composer的自动加载器将自动包含用于在项目中使用的函数。函数的API如下。

/**
 * Creates a docker image based on the requested language with the given user
 * script added to the image for execution.
 *
 * @param string $languageName One of the supported languages.
 * @param string $script The file path to the user's submission to test.
 * @param string|null $constantName The name of the constant to set, if a
 *     constant is being used.
 * @param mixed|null $constantValue The value of the constant to set, if a
 *     constant is being used.
 * @return array A description of the docker image that was created.
 * @throws Exception if unable to create docker image
 */
function createImage(
    $languageName,
    $script,
    $constantName = null,
    $constantValue = null
);

/**
 * Loads the hole configuration for an included hole.  If you want to add your
 * own holes outside of this project, you don't need to call this function.
 *
 * @param string|callable $hole One of the included holes specified by name, or
       a hole specification wrapped in a closure.
 * @return array The hole's configuration.  Included fields:
 *     string|null constantName The name of the constant that will hold
 *         input.
 *         This may be a callable as well, with 0 arguments.
 *     array constantValues The different values of input to test.
 *         This may be a callable as well, with 0 arguments.
 *     callable|null trim What kind of trim to apply to the results
 *         before comparison.
 *     string sample The expected output for the hole.
 *         This may be a callable as well, with 1 argument containing the
           constant value for input.
 */
function loadHole($hole);

/**
 * Judges the user submission for a language against the given hole
 * configuration.
 *
 * @param array $hole The hole's configuration.  @see loadHole() for details.
 * @param string $languageName One of the supported languages.
 * @param string $script The file path to the user's submission to test.
 * @return array The results of judging the submission and the details of the
 *     submission's last run.  Included fields:
 *     bool result Whether the submission passed the tests or not.
 *     int exitStatus The exit status of the command.
 *     string output The output, trimmed according to the rules of the hole.
 *     string sample The expected output, trimmed according to the rules of
 *         the hole.
 *     string stderr The stderr output.
 *     string|null constantName The constant's name, if used.
 *     mixed|null constantValue The constant's value, if used.
 */
function judge(array $hole, $languageName, $script);

以下是如何用它来评判用户提交的一个示例

<?php
$holeName = 'fizzbuzz';
$language = 'php-5.5';
$userScript = $_FILES['submission']['tmp_name'];
$result = \Bizgolf\judge(\Bizgolf\loadHole($holeName), $language, $userScript);
if ($result['result']) {
    echo "Successful submission!\n";
} else {
    echo "Submission failed validation.  Try again.\n";
}

CLI使用

在bin目录中包含了一个有限的php命令行judge命令。它的用法是

judge LANGUAGE HOLE USER_SUBMISSION

语言和洞是这个存储库中的文件名,用户提交是评判脚本的路径。如果提交通过了洞,则此命令将以状态码0退出,如果没有通过,则以状态码1退出。

贡献

欢迎在GitHub上提交任何更改、建议或错误报告。欢迎Pull请求!

新增语言

请确保语言锁定行为,不允许网络访问、文件系统访问或进程执行。这是为了消除常见的“作弊”途径,例如从提供解决方案的网站上下载结果。

语言应包含一个语言定义,这是一个返回包含以下内容的PHP脚本的脚本:

  • 一个tagName(也作为Dockerfile所在目录的名称),
  • 一个addConstant函数,它接受用户脚本、常量名称和常量值作为参数,并应返回脚本,但添加了将常量名称设置为给定值的必要代码,
  • 以及一个executeCommand字符串,它提供要运行的命令。此脚本将传递用户脚本的路径,应退出并返回执行用户脚本的状态,并转发该脚本的标准输出和标准错误。

在languages/tagName/Dockerfile中应有一个Dockerfile,它应创建一个新Docker镜像,安装并配置目标语言,以便按描述锁定访问。

新增漏洞

bizgolf漏洞是一个简单的PHP文件,返回包含该漏洞期望的详细信息的数组。以下示例(来自fizzbuzz)显示了一些允许的字段

<?php
return [
    'constantName' => 'NUM',
    'constantValues' => function() {
        $values = [100, 1000];
        for ($i = 0; $i < 8; $i++) {
            $values[] = rand(101, 999);
        }

        return $values;
    },
    'trim' => 'rtrim',
    'sample' => function($num) {
        $result = '';
        for ($i = 1; $i <= $num; $i++) {
            if ($i % 15 == 0) {
                $result .= "FizzBuzz\n";
            } elseif ($i % 3 == 0) {
                $result .= "Fizz\n";
            } elseif ($i % 5 == 0) {
                $result .= "Buzz\n";
            } else {
                $result .= "$i\n";
            }
        }

        return $result;
    },
];

请确保您的漏洞将提供适当的挑战,并且可以在许多语言中很好地工作。

许可证

bizgolf采用MIT许可证。有关完整许可证文本,请参阅LICENSE