Skip to content

Commit

Permalink
Add tags to setting info, and add batch/settings.php --filter.
Browse files Browse the repository at this point in the history
  • Loading branch information
kohler committed Sep 11, 2024
1 parent e41fb9f commit 679e872
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 51 deletions.
41 changes: 33 additions & 8 deletions batch/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class Settings_Batch {
public $dry_run;
/** @var bool */
public $diff;
/** @var ?SearchExpr */
private $filter;

function __construct(Contact $user, $arg) {
$this->conf = $user->conf;
Expand All @@ -40,23 +42,44 @@ function __construct(Contact $user, $arg) {
}
$this->dry_run = isset($arg["dry-run"]);
$this->diff = isset($arg["diff"]);
$filter = $exclude = null;
foreach ($arg["filter"] ?? [] as $s) {
$ss = new SearchSplitter($s);
if (($expr = $ss->parse_expression(SearchOperatorSet::simple_operators()))) {
$filter = $filter ? SearchExpr::combine("or", $filter, $expr) : $expr;
}
}
foreach ($arg["exclude"] ?? [] as $s) {
$ss = new SearchSplitter($s);
if (($expr = $ss->parse_expression(SearchOperatorSet::simple_operators()))) {
$exclude = $exclude ? SearchExpr::combine("or", $exclude, $expr) : $expr;
}
}
if ($exclude) {
$exclude = SearchExpr::combine("not", $exclude);
$filter = $filter ? SearchExpr::combine("and", $filter, $exclude) : $exclude;
}
$this->filter = $filter;
if ($this->filter && ($this->filename || $this->expr)) {
throw new CommandLineException("`--filter` and `--exclude` are incompatible with changing settings");
}
}

/** @param bool $new
* @return string */
static function output(SettingValues $sv, $new) {
return json_encode($sv->all_jsonv(["new" => $new]), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
function output(SettingValues $sv, $new) {
return json_encode($sv->all_jsonv(["new" => $new, "filter" => $this->filter]), JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) . "\n";
}

/** @return int */
function run() {
if ($this->filename === null && $this->expr === null) {
fwrite(STDOUT, self::output($this->sv, false));
fwrite(STDOUT, $this->output($this->sv, false));
return 0;
}

if ($this->diff) {
$old_jsonstr = self::output(new SettingValues($this->user), false);
$old_jsonstr = $this->output(new SettingValues($this->user), false);
} else {
$old_jsonstr = null;
}
Expand Down Expand Up @@ -95,10 +118,10 @@ function run() {
$dmp = new dmp\diff_match_patch;
$dmp->Line_Histogram = true;
if ($this->dry_run) {
assert(self::output($this->sv, false) === $old_jsonstr);
$new_jsonstr = self::output($this->sv, true);
assert($this->output($this->sv, false) === $old_jsonstr);
$new_jsonstr = $this->output($this->sv, true);
} else {
$new_jsonstr = self::output(new SettingValues($this->user), false);
$new_jsonstr = $this->output(new SettingValues($this->user), false);
}
$diff = $dmp->line_diff($old_jsonstr, $new_jsonstr);
fwrite(STDOUT, $dmp->line_diff_toUnified($diff));
Expand All @@ -115,7 +138,9 @@ static function make_args($argv) {
"dry-run,d Do not modify settings",
"diff Write unified settings diff of changes",
"expr:,e: =JSON Change settings via JSON",
"file:,f: =FILE Change settings via FILE"
"file:,f: =FILE Change settings via FILE",
"filter[] =EXPR Only include settings matching EXPR",
"exclude[] =EXPR Exclude settings matching EXPR"
)->description("Query or modify HotCRP settings in JSON format.
Usage: php batch/settings.php > JSONFILE
php batch/settings.php FILE
Expand Down
54 changes: 36 additions & 18 deletions etc/settinginfo.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
"name": "conference_abbreviation", "storage": "opt.shortName",
"title": "Conference abbreviation",
"type": "simplestring", "size": 20, "autogrow": true,
"parser_class": "Basics_SettingParser"
"parser_class": "Basics_SettingParser",
"tags": ["id"]
},
{
"name": "conference_name", "storage": "opt.longName",
"title": "Conference name", "placeholder": "(same as abbreviation)",
"type": "simplestring", "size": 70,
"parser_class": "Basics_SettingParser"
"parser_class": "Basics_SettingParser",
"tags": ["id"]
},

{
Expand Down Expand Up @@ -79,7 +81,8 @@
{
"name": "final_done",
"title": "Final version upload hard deadline",
"type": "date"
"type": "date",
"tags": ["time"]
},
{
"name": "final_grace",
Expand All @@ -89,12 +92,14 @@
{
"name": "final_open",
"title": "Collect final versions setting",
"type": "checkbox"
"type": "checkbox",
"tags": ["time"]
},
{
"name": "final_soft",
"title": "Final version upload deadline",
"type": "date"
"type": "date",
"tags": ["time"]
},
{
"name": "mailbody_requestreview",
Expand Down Expand Up @@ -479,11 +484,13 @@
},
{
"name_pattern": "response/$/open",
"title": "/Start time", "type": "date"
"title": "/Start time", "type": "date",
"tags": ["time"]
},
{
"name_pattern": "response/$/done",
"title": "/Hard deadline", "type": "date"
"title": "/Hard deadline", "type": "date",
"tags": ["time"]
},
{
"name_pattern": "response/$/grace",
Expand Down Expand Up @@ -516,7 +523,8 @@
{
"name": "review_open", "storage": "rev_open",
"title": "Enable reviewing",
"type": "cdate"
"type": "cdate",
"tags": ["time"]
},
{
"name": "review_blind", "storage": "rev_blind",
Expand Down Expand Up @@ -625,22 +633,26 @@
{
"name_pattern": "review/$/soft",
"title": "/Deadline",
"type": "date", "placeholder": "none"
"type": "date", "placeholder": "none",
"tags": ["time"]
},
{
"name_pattern": "review/$/done",
"title": "/Hard deadline",
"type": "date", "placeholder": "none"
"type": "date", "placeholder": "none",
"tags": ["time"]
},
{
"name_pattern": "review/$/external_soft",
"title": "/External deadline",
"type": "date", "subtype": "explicit_none", "placeholder": "same as PC"
"type": "date", "subtype": "explicit_none", "placeholder": "same as PC",
"tags": ["time"]
},
{
"name_pattern": "review/$/external_done",
"title": "/External hard deadline",
"type": "date", "subtype": "explicit_none", "placeholder": "same as PC"
"type": "date", "subtype": "explicit_none", "placeholder": "same as PC",
"tags": ["time"]
},
{
"name": "review_default_round_index", "storage": "none", "json": false,
Expand Down Expand Up @@ -810,20 +822,23 @@
"title": "Decision visibility to authors",
"type": "radio",
"values": [0, 2, 1], "default_value": 0,
"json_values": ["no", "yes", "condition"]
"json_values": ["no", "yes", "condition"],
"tags": ["final"]
},
{
"name": "decision_visibility_author_condition", "storage": "dat.au_seedec",
"title": "Decision visibility condition",
"type": "string", "subtype": "search", "size": 30, "placeholder": "Search",
"parser_class": "DecisionVisibility_SettingParser"
"parser_class": "DecisionVisibility_SettingParser",
"tags": ["final"]
},
{
"name": "decision_visibility_reviewer", "storage": "seedec",
"title": "Decision visibility for reviewers",
"type": "radio",
"values": [0, 3, 1], "default_value": 0,
"json_values": ["no", "unconflicted", "yes"]
"json_values": ["no", "unconflicted", "yes"],
"tags": ["final"]
},
{
"name": "decision_visibility", "storage": "none",
Expand Down Expand Up @@ -920,18 +935,21 @@
{
"name": "submission_open", "storage": "sub_open",
"title": "Enable submissions",
"type": "cdate"
"type": "cdate",
"tags": ["time"]
},
{
"name": "submission_registration", "storage": "sub_reg",
"title": "Submission registration deadline",
"type": "date", "parse_order": 0
"type": "date", "parse_order": 0,
"tags": ["time"]
},
{
"name": "submission_done", "storage": "sub_sub",
"title": "Submission deadline",
"type": "date", "parse_order": 1,
"parser_class": "Submissions_SettingParser"
"parser_class": "Submissions_SettingParser",
"tags": ["time"]
},
{
"name": "submission_update", "storage": "sub_update",
Expand Down
5 changes: 1 addition & 4 deletions src/papersearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -842,10 +842,7 @@ static private function _canonical_expression($str, $type, $qt, Conf $conf, $dep
$splitter = new SearchSplitter($str);
$sa = $splitter->parse_expression(null, $type === "all" ? "SPACE" : "SPACEOR");
if ($type === "none" && $sa) {
$op = SearchOperatorSet::paper_search_operators()->lookup("NOT");
$sax = SearchExpr::make_op($op, 0, strlen($str), null);
$sax->child[] = $sa;
$sa = $sax;
$sa = SearchExpr::combine("not", $sa);
}
return self::_canonicalize_atom($sa, $type, $qt, $conf, $depth);
}
Expand Down
52 changes: 46 additions & 6 deletions src/searchexpr.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,27 +52,37 @@ static function make_keyword($kword, $text, $kwpos1, $pos1, $pos2, $parent = nul
}

/** @param SearchOperator $op
* @param int $kwpos1
* @param int $kwpos2
* @param int $pos1
* @param int $pos2
* @param ?SearchExpr $reference
* @return SearchExpr */
static function make_op($op, $kwpos1, $kwpos2, $reference) {
static function make_op_start($op, $pos1, $pos2, $reference) {
$sa = new SearchExpr;
$sa->op = $op;
if ($op->unary()) {
$sa->kwpos1 = $sa->pos1 = $kwpos1;
$sa->pos2 = $kwpos2;
$sa->kwpos1 = $sa->pos1 = $pos1;
$sa->pos2 = $pos2;
$sa->child = [];
$sa->parent = $reference;
} else {
$sa->kwpos1 = $sa->pos1 = $reference->pos1;
$sa->pos2 = $kwpos2;
$sa->pos2 = $pos2;
$sa->child = [$reference];
$sa->parent = $reference->parent;
}
return $sa;
}

/** @param 'and'|'or'|'xor'|'not' $opname
* @param SearchExpr ...$child
* @return SearchExpr */
static function combine($opname, ...$child) {
$sa = new SearchExpr;
$sa->op = SearchOperatorSet::simple_operator($opname);
$sa->child = $child;
return $sa;
}

/** @return bool */
function is_complete() {
return !$this->op || count($this->child) > ($this->op->unary() ? 0 : 1);
Expand Down Expand Up @@ -179,4 +189,34 @@ function unparse_json($str = null) {
return (object) $a;
}
}

/** @param callable(SearchExpr):bool $f
* @return bool
* @suppress PhanTypeArraySuspiciousNullable */
function evaluate_simple($f) {
if (!$this->op) {
$ok = $f($this);
} else if (($this->op->flags & SearchOperator::F_AND) !== 0) {
$ok = true;
foreach ($this->child as $ch) {
$ok = $ok && $ch->evaluate_simple($f);
}
} else if (($this->op->flags & SearchOperator::F_OR) !== 0) {
$ok = false;
foreach ($this->child as $ch) {
$ok = $ok || $ch->evaluate_simple($f);
}
} else if (($this->op->flags & SearchOperator::F_XOR) !== 0) {
$ok = false;
foreach ($this->child as $ch) {
if ($ch->evaluate_simple($f))
$ok = !$ok;
}
} else if (($this->op->flags & SearchOperator::F_NOT) !== 0) {
$ok = !$this->child[0] || !$this->child[0]->evaluate_simple($f);
} else {
throw new ErrorException("unknown operator");
}
return $ok;
}
}
13 changes: 9 additions & 4 deletions src/searchoperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,15 @@ class SearchOperator {
* @readonly */
public $flags;

const F_UNARY = 1;
const F_ALLOW_SUBTYPE = 2;
const F_SUBTYPE = 4;
const F_UNNAMED = 8;
const F_UNARY = 0x1;
const F_ALLOW_SUBTYPE = 0x2;
const F_SUBTYPE = 0x4;
const F_UNNAMED = 0x8;
const F_NOT = 0x10;
const F_AND = 0x20;
const F_OR = 0x40;
const F_XOR = 0x80;
const F_SIMPLEOPS = 0xF0;

/** @param string $type
* @param int $precedence
Expand Down
Loading

0 comments on commit 679e872

Please sign in to comment.