From 5b0d0916b27f271fc12a8c0c6b595e11673d306d Mon Sep 17 00:00:00 2001 From: "A. Wilcox" Date: Tue, 8 Oct 2019 19:55:53 -0500 Subject: hscript: Implement 'hostname' parsing; add rest of existing manual tests --- hscript/CMakeLists.txt | 1 + hscript/meta.cc | 41 +++++++++++++++++++++++++++++++++++++++++ hscript/meta.hh | 11 +++++++++++ hscript/script.cc | 34 +++++++++++++++++++++++----------- tests/spec/validator.rb | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 11 deletions(-) create mode 100644 hscript/meta.cc diff --git a/hscript/CMakeLists.txt b/hscript/CMakeLists.txt index 65126e4..02ef574 100644 --- a/hscript/CMakeLists.txt +++ b/hscript/CMakeLists.txt @@ -1,6 +1,7 @@ set(HSCRIPT_SOURCE script.cc key.cc + meta.cc network.cc ) diff --git a/hscript/meta.cc b/hscript/meta.cc new file mode 100644 index 0000000..83c6269 --- /dev/null +++ b/hscript/meta.cc @@ -0,0 +1,41 @@ +/* + * metadata.cc - Implementation of the Key classes for system metadata + * libhscript, the HorizonScript library for + * Project Horizon + * + * Copyright (c) 2019 Adélie Linux and contributors. All rights reserved. + * This code is licensed under the AGPL 3.0 license, as noted in the + * LICENSE-code file in the root directory of this repository. + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +#include +#include "meta.hh" +#include "util/output.hh" + +using namespace Horizon::Keys; + +Key *Hostname::parseFromData(const std::string data, int lineno, int *errors, + int *warnings) { + std::regex valid_re("[A-Za-z0-9.]*"); + bool valid = std::regex_match(data, valid_re); + if(!valid) { + if(errors) *errors += 1; + output_error("installfile:" + std::to_string(lineno), + "hostname: expected machine or DNS name", + "'" + data + "' is not a valid hostname"); + return nullptr; + } + return new Hostname(lineno, data); +} + +bool Hostname::validate() const { + /* Validate that the name is a valid machine or DNS name */ + return false; +} + +bool Hostname::execute() const { + /* Write the hostname to /etc/hostname in the target environment. */ + return false; +} diff --git a/hscript/meta.hh b/hscript/meta.hh index 9491aac..626ce91 100644 --- a/hscript/meta.hh +++ b/hscript/meta.hh @@ -13,12 +13,23 @@ #ifndef __HSCRIPT_META_HH_ #define __HSCRIPT_META_HH_ +#include #include "key.hh" namespace Horizon { namespace Keys { class Hostname : public Key { +private: + const std::string _name; + Hostname(int _line, const std::string my_name) : Key(_line), + _name(my_name) {} +public: + static Key *parseFromData(const std::string data, int lineno, int *errors, + int *warnings); + const std::string name() const { return this->_name; } + bool validate() const override; + bool execute() const override; }; class PkgInstall : public Key { diff --git a/hscript/script.cc b/hscript/script.cc index a8101dc..8c0c380 100644 --- a/hscript/script.cc +++ b/hscript/script.cc @@ -85,24 +85,36 @@ struct Script::ScriptPrivate { */ bool store_key(const std::string key_name, Keys::Key *key_obj, int lineno, int *errors, int *warnings) { +#define DUPLICATE_ERROR(OBJ, KEY, OLD_VAL) \ + std::string err_str("previous value was ");\ + err_str += OLD_VAL;\ + err_str += " at installfile:" + std::to_string(OBJ->lineno());\ + if(errors) *errors += 1;\ + output_error("installfile:" + std::to_string(lineno),\ + "duplicate value for key '" + KEY + "'", err_str); + if(key_name == "network") { if(this->network) { - std::string err_str("previous value was "); - err_str += this->network->test() ? "true" : "false"; - err_str += " at installfile:"; - err_str += std::to_string(this->network->lineno()); - if(errors) *errors += 1; - output_error("installfile:" + std::to_string(lineno), - "duplicate value for key 'network'", - err_str); + DUPLICATE_ERROR(this->network, std::string("network"), + this->network->test() ? "true" : "false") return false; } - std::unique_ptr net(dynamic_cast(key_obj)); + std::unique_ptr net( + dynamic_cast(key_obj) + ); this->network = std::move(net); return true; } else if(key_name == "hostname") { - /*! TODO: implement */ - return false; + if(this->hostname) { + DUPLICATE_ERROR(this->hostname, std::string("hostname"), + this->hostname->name()) + return false; + } + std::unique_ptr name( + dynamic_cast(key_obj) + ); + this->hostname = std::move(name); + return true; } else if(key_name == "pkginstall") { /*! TODO: implement */ return false; diff --git a/tests/spec/validator.rb b/tests/spec/validator.rb index bd53853..e54d40e 100644 --- a/tests/spec/validator.rb +++ b/tests/spec/validator.rb @@ -50,6 +50,16 @@ RSpec.describe 'HorizonScript Validation Utility', :type => :aruba do run_validate expect(last_command_started).to have_output(SUCCESS_OUTPUT) end + it "requires keys to have values" do + use_fixture '0015-keys-without-values.installfile' + run_validate ' --keep-going' + expect(last_command_started).to have_output(/5 error(s)/) + end + it "fails on lines over maximum line length" do + use_fixture '0017-line-too-long.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*length/) + end context "required keys" do it "fails without a 'network' key" do use_fixture '0006-no-network.installfile' @@ -77,6 +87,28 @@ RSpec.describe 'HorizonScript Validation Utility', :type => :aruba do expect(last_command_started).to have_output(/error: .*mount.*/) end end + context "values" do + it "fails with an invalid 'network' value" do + use_fixture '0011-invalid-network.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*network.*/) + end + it "fails with an invalid 'hostname' value" do + use_fixture '0012-invalid-hostname.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*hostname.*/) + end + it "fails with an invalid 'rootpw' value" do + use_fixture '0013-invalid-rootpw.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*rootpw.*/) + end + it "fails with an invalid 'mount' value" do + use_fixture '0014-invalid-mount.installfile' + run_validate + expect(last_command_started).to have_output(/error: .*mount.*/) + end + end context "unique keys" do it "fails with a duplicate 'network' key" do use_fixture '0018-duplicate-network.installfile' -- cgit v1.2.3-60-g2f50