Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 12 additions & 12 deletions levels/checkers/start-here.sh
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
#!/bin/bash

source ./common.sh
source $(dirname $0)/common.sh

read old new ref < /dev/stdin

dump_dir=$(dump-commit-to-directory $new)

pushd dump_dir
# Check file existence.
if [ ! -f alice.txt ];
then reject-solution "Alice is missing! Try again.";
fi
pushd $dump_dir
# Check file existence.
if [ ! -f alice.txt ];
then reject-solution "Alice is missing! Try again.";
fi

if [ ! -f bob.txt ];
then reject-solution "Bob is missing! Try again.";
fi
if [ ! -f bob.txt ];
then reject-solution "Bob is missing! Try again.";
fi
popd

git fetch --tags --quiet # get all the tags but don't show them to the user
# Check how many commits the user needed - should be two (the user commit + merge commit)!
commit_amount=$( git log start-here-tag..$new --oneline | wc -l )
if [ $commit_amount -ne 1 ];
then reject-solution "The files should have been added in a single commit, but I've found ${commit_amount} commits in the log. To reset and try again, delete your local start-here branch, checkout the original start-here branch again and try again.";
then reject-solution "The files should have been added in a single commit, but I've found ${commit_amount} commits in the log. To reset and try again, delete your local start-here branch, checkout the original start-here branch again and try again.";
fi

# We know that there's only one commit in the changes - otherwise it would have failed before.
number_of_files_changed=$( git diff --stat $old $new | grep "files changed" | awk ' {print $1} ' )
number_of_files_changed=$( git diff --stat $old $new | grep "files changed" | awk ' {print $1} ' )
if [[ $number_of_files_changed -ne 2 ]]
then bad "More than 2 files were changed! Only add alice.txt and bob.txt. Check out the original branch and try again.";
then reject-solution "More than 2 files were changed! Only add alice.txt and bob.txt. Check out the original branch and try again.";
fi

32 changes: 25 additions & 7 deletions levels/game-config.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,36 @@
[levels]
[levels.clone]
[[levels]]
title = "clone"
branch = "master"
solutionCheckers = []
solution_checker = "echo No pushing to master. Read the README file; exit 1"
flags = [] # ["start-here"], but it's implicit in the readme

[levels.start-here]
[[levels]]
title = "start-here"
branch = "start-here"
solutionChecker = "checkers/start-here.sh"
solution_checker = "hooks/checkers/start-here.sh"
flags = ["merge-1"]

[levels.merge-1]
[[levels]]
title = "merge-1"
branch = "fizzling-vulture-pedial"
solutionChecker = "checkers/merge-1.sh"
solution_checker = "hooks/checkers/merge-1.sh"
flags = ["merge-2", "log-1"]

[[levels]]
title = "merge-2"
branch = "ironish-quartzic-brahmas"
solution_checker = "hooks/checkers/merge-2.sh"
flags = ["merge-3"]

[[levels]]
title = "log-1"
branch = "akmite-radicle-garce"
solution_checker = "echo No pushing in this stage. ; exit 1"
flags = ["log-2"]

[[levels]]
title = "log-2"
branch = "alibies-listwork-homotaxy"
solution_checker = "hooks/checkers/log-2.sh"
flags = ["log-3"]

3 changes: 3 additions & 0 deletions scripts/generate-pre-receive-hook/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Script puts files here by default. Let's avoid commiting them if possible
output/

5 changes: 5 additions & 0 deletions scripts/generate-pre-receive-hook/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,9 @@ edition = "2018"

[dependencies]
structopt = "0.3.13"
serde = { version = "1.0", features = ["derive"] }
toml = "0.5"
tinytemplate = "1.0.4"
simple_logger = "1.6.0"
log = "0.4"

95 changes: 87 additions & 8 deletions scripts/generate-pre-receive-hook/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,110 @@
use log;
use log::{debug, info};
use serde::{Deserialize, Serialize};
use simple_logger;
use std::fs;
use std::io::Write;
use structopt::StructOpt;
use tinytemplate::TinyTemplate;
use toml;

// Search for a pattern in a file and display the lines that contain it.
#[derive(Debug, StructOpt)]
#[structopt(about = "A script to generate the master pre-receive hook file.")]
struct Cli {
// The path to the file to read
#[structopt(parse(from_os_str))]
#[structopt(parse(from_os_str), help = "Path to game config file to read")]
game_config_path: std::path::PathBuf,

#[structopt(parse(from_os_str), help = "Path to template file to read")]
template_path: std::path::PathBuf,

#[structopt(
parse(from_os_str),
default_value = "output/pre-receive",
help = "Path to output file (creates if doesn't exist)"
)]
output_path: std::path::PathBuf,

#[structopt(
short = "v",
long = "verbose",
help = "Show more information about the actions taken"
)]
verbose: bool,
}

#[derive(Debug, Clone, Deserialize, Serialize)]
struct Level {
title: String,
branch: String,
solution_checke: String,
solution_checker: String,
flags: Vec<String>,
}

#[derive(Debug, Deserialize, Serialize)]
struct GameConfig {
levels: Vec<Level>,
}

fn replace_flags_with_branch_names(game_config: &mut GameConfig) {
let levels_info = game_config.levels.clone();

for mut level in &mut game_config.levels {
let mut new_flags = Vec::new();
for flag in &level.flags {
debug!("level {} flag {}", level.title, flag);
let mut levels_iterator = levels_info.iter();
let found = levels_iterator.find(|&x| &x.title == flag);
match found {
Some(x) => {
debug!("replacing {} with {}", flag, x.branch);
new_flags.push(String::from(&x.branch));
}
None => {
debug!("flag {} is final", flag);
new_flags.push(flag.to_string());
}
}
}
level.flags = new_flags;
}
}

fn main() {
let args = Cli::from_args();
println!("Loading script from {:?}", args);

let game_config_file_contents =
fs::read_to_string(args.game_config_path).expect("Couldn't read the config file!");
if args.verbose {
simple_logger::init_with_level(log::Level::Debug).unwrap();
} else {
simple_logger::init_with_level(log::Level::Info).unwrap();
};

info!("Reading script from {:?}", args.game_config_path);
let game_config_file_contents = fs::read_to_string(args.game_config_path).unwrap();

let mut game_config: GameConfig = toml::from_str(&game_config_file_contents).unwrap();
debug!("Game config before editing: {:?}\n", game_config);

replace_flags_with_branch_names(&mut game_config);

debug!("Game config after editing: {:?}\n", game_config);

info!("Reading template from {:?}", args.template_path);
let template_file_contents = fs::read_to_string(args.template_path).unwrap();

let mut tt = TinyTemplate::new();
let template_name = "switch_case";
tt.add_template(template_name, &template_file_contents)
.unwrap();
let rendered = tt.render(template_name, &game_config).unwrap();

debug!("########## RENDERED TEMPLATE ##########");
debug!("{}\n", rendered);

let mut output_dir = args.output_path.clone();
output_dir.pop();
fs::create_dir_all(&output_dir).expect("Failed to create parent dir");
let mut output_file = fs::File::create(&args.output_path).expect("Couldn't create file!");
output_file.write_all(&rendered.as_bytes()).unwrap();

println!("{}", game_config_file_contents);
info!("Wrote rendered file to {:?}", args.output_path);
}
19 changes: 19 additions & 0 deletions scripts/generate-pre-receive-hook/template.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

read old new ref < /dev/stdin

branch_name=$(echo $ref | awk 'BEGIN \{ FS = "/" } ; \{ print $NF }')

print_flags () \{
if [[ $# -eq 1 ]]
then echo "You won! The flag is "$1
else
echo "You won! The flags are "$@
fi
}

case $branch_name in
{{ for level in levels }}{level.branch})
echo $old $new $ref | {level.solution_checker} && print_flags{{ for levelflag in level.flags }} {levelflag}{{ endfor }}
;;
{{ endfor }}esac