diff --git a/grive/src/main.cc b/grive/src/main.cc index 9516a2c..cf3a3d1 100644 --- a/grive/src/main.cc +++ b/grive/src/main.cc @@ -46,9 +46,6 @@ const std::string client_id = "22314510474.apps.googleusercontent.com" ; const std::string client_secret = "bl4ufi89h-9MkFlypcI7R785" ; -const std::string defaultRootFolder = "."; -const std::string defaultConfigFileName = ".grive"; -const char *configFileEnvironmentVariable = "GR_CONFIG"; using namespace gr ; namespace po = boost::program_options; @@ -105,8 +102,6 @@ int Main( int argc, char **argv ) { InitGCrypt() ; - std::string rootFolder = defaultRootFolder; - // construct the program options po::options_description desc( "Grive options" ); desc.add_options() @@ -129,6 +124,7 @@ int Main( int argc, char **argv ) po::store(po::parse_command_line( argc, argv, desc), vm ); po::notify(vm); + // simple commands that doesn't require log or config if ( vm.count("help") ) { std::cout << desc << std::endl ; @@ -144,31 +140,9 @@ int Main( int argc, char **argv ) // initialize logging InitLog(vm) ; - boost::shared_ptr config ; + Config config(vm) ; - // config file will be (in order of preference) - // value specified in environment string - // value specified in defaultConfigFileName in path from commandline --path - // value specified in defaultConfigFileName in current directory - const char *envConfigFileName = ::getenv( configFileEnvironmentVariable ) ; - if (envConfigFileName) { - config.reset(new Config(envConfigFileName)); - - } else if ( vm.count( "path" ) ) { - rootFolder = vm["path"].as(); - config.reset(new Config( fs::path(rootFolder) / fs::path(defaultConfigFileName) )); - - } else { - config.reset(new Config( defaultConfigFileName) ); - } - - // misc options - Json options ; - options.Add( "log-xml", Json(vm.count("log-xml") > 0) ) ; - options.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ; - options.Add( "force", Json(vm.count("force") > 0 ) ) ; - - Log( "config file name %1%", config->ConfigFile().string(), log::verbose ); + Log( "config file name %1%", config.Filename(), log::verbose ); if ( vm.count( "auth" ) ) { @@ -188,14 +162,14 @@ int Main( int argc, char **argv ) token.Auth( code ) ; // save to config - config->Get().Add( "refresh_token", Json( token.RefreshToken() ) ) ; - config->Save() ; + config.Set( "refresh_token", Json( token.RefreshToken() ) ) ; + config.Save() ; } std::string refresh_token ; try { - refresh_token = config->Get()["refresh_token"].Str() ; + refresh_token = config.Get("refresh_token").Str() ; } catch ( Exception& e ) { @@ -210,7 +184,7 @@ int Main( int argc, char **argv ) OAuth2 token( refresh_token, client_id, client_secret ) ; AuthAgent agent( token, std::auto_ptr( new http::CurlAgent ) ) ; - Drive drive( &agent, options, rootFolder ) ; + Drive drive( &agent, config.GetAll() ) ; drive.DetectChanges() ; if ( vm.count( "dry-run" ) == 0 ) @@ -221,7 +195,7 @@ int Main( int argc, char **argv ) else drive.DryRun() ; - config->Save() ; + config.Save() ; Log( "Finished!", log::info ) ; return 0 ; } diff --git a/libgrive/src/drive/Drive.cc b/libgrive/src/drive/Drive.cc index 028e62c..82cfc74 100644 --- a/libgrive/src/drive/Drive.cc +++ b/libgrive/src/drive/Drive.cc @@ -51,10 +51,10 @@ namespace const std::string state_file = ".grive_state" ; } -Drive::Drive( http::Agent *http, const Json& options, const std::string &rootFolder) : - m_http( http ), - m_state( fs::path(rootFolder), fs::path(rootFolder) / fs::path(state_file), options ), - m_rootFolder(rootFolder), +Drive::Drive( http::Agent *http, const Json& options ) : + m_http ( http ), + m_root ( options["path"].Str() ), + m_state ( m_root / state_file, options ), m_options ( options ) { assert( m_http != 0 ) ; @@ -128,7 +128,7 @@ void Drive::SyncFolders( ) void Drive::DetectChanges() { Log( "Reading local directories", log::info ) ; - m_state.FromLocal( m_rootFolder ) ; + m_state.FromLocal( m_root ) ; long prev_stamp = m_state.ChangeStamp() ; Trace( "previous change stamp is %1%", prev_stamp ) ; diff --git a/libgrive/src/drive/Drive.hh b/libgrive/src/drive/Drive.hh index bcae37c..5424f44 100644 --- a/libgrive/src/drive/Drive.hh +++ b/libgrive/src/drive/Drive.hh @@ -40,7 +40,7 @@ class Entry ; class Drive { public : - Drive( http::Agent *http, const Json& options, const std::string &rootFolder ) ; + Drive( http::Agent *http, const Json& options ) ; void DetectChanges() ; void Update() ; @@ -59,8 +59,8 @@ private : private : http::Agent *m_http ; std::string m_resume_link ; + fs::path m_root ; State m_state ; - fs::path m_rootFolder; Json m_options ; } ; diff --git a/libgrive/src/drive/Resource.cc b/libgrive/src/drive/Resource.cc index 53e4fc4..e64bd0f 100644 --- a/libgrive/src/drive/Resource.cc +++ b/libgrive/src/drive/Resource.cc @@ -58,8 +58,8 @@ const std::string xml_meta = /// default constructor creates the root folder -Resource::Resource(const fs::path& rootFolder) : - m_name ( rootFolder.string() ), +Resource::Resource(const fs::path& root_folder) : + m_name ( root_folder.string() ), m_kind ( "folder" ), m_id ( "folder:root" ), m_href ( root_href ), diff --git a/libgrive/src/drive/Resource.hh b/libgrive/src/drive/Resource.hh index 9406c6f..5d4f034 100644 --- a/libgrive/src/drive/Resource.hh +++ b/libgrive/src/drive/Resource.hh @@ -51,7 +51,7 @@ public : typedef Children::const_iterator iterator ; public : - Resource(const fs::path& rootFolder) ; + Resource(const fs::path& root_folder) ; Resource( const std::string& name, const std::string& kind ) ; // default copy ctor & op= are fine diff --git a/libgrive/src/drive/State.cc b/libgrive/src/drive/State.cc index cd2aec6..43e6367 100644 --- a/libgrive/src/drive/State.cc +++ b/libgrive/src/drive/State.cc @@ -32,9 +32,9 @@ namespace gr { -State::State( const fs::path& rootFolder, const fs::path& filename, const Json& options ) : - m_res(rootFolder), - m_cstamp( -1 ) +State::State( const fs::path& filename, const Json& options ) : + m_res ( options["path"].Str() ), + m_cstamp ( -1 ) { Read( filename ) ; diff --git a/libgrive/src/drive/State.hh b/libgrive/src/drive/State.hh index 2cc2405..a0e1213 100644 --- a/libgrive/src/drive/State.hh +++ b/libgrive/src/drive/State.hh @@ -43,7 +43,7 @@ public : typedef ResourceTree::iterator iterator ; public : - explicit State( const fs::path& rootFolder, const fs::path& filename, const Json& options ) ; + explicit State( const fs::path& filename, const Json& options ) ; ~State() ; void FromLocal( const fs::path& p ) ; diff --git a/libgrive/src/util/Config.cc b/libgrive/src/util/Config.cc index 62a8333..1a19eff 100644 --- a/libgrive/src/util/Config.cc +++ b/libgrive/src/util/Config.cc @@ -26,39 +26,80 @@ #include #include +namespace po = boost::program_options; + namespace gr { -Config::Config(const fs::path& configFile) : - m_configFile(configFile), - m_cfg( Read() ) +const std::string default_filename = ".grive"; +const char *env_name = "GR_CONFIG"; +const std::string default_root_folder = "."; + +Config::Config( const fs::path& root_path ) : + m_path( GetPath( root_path ) ) { - if (configFile.empty()) - { - throw Error() << expt::ErrMsg("Config cannot be initalised with an empty string."); - } + m_file = Read() ; } -const fs::path& Config::ConfigFile() const +Config::Config( const po::variables_map& vm ) { - return m_configFile ; + m_cmd.Add( "log-xml", Json(vm.count("log-xml") > 0) ) ; + m_cmd.Add( "new-rev", Json(vm.count("new-rev") > 0) ) ; + m_cmd.Add( "force", Json(vm.count("force") > 0 ) ) ; + m_cmd.Add( "path", Json(vm.count("path") > 0 + ? vm["path"].as() + : default_root_folder ) ) ; + + m_path = GetPath( fs::path(m_cmd["path"].Str()) ) ; + m_file = Read( ) ; +} + +fs::path Config::GetPath( const fs::path& root_path ) +{ + // config file will be (in order of preference) + // value specified in environment string + // value specified in defaultConfigFileName in path from commandline --path + // value specified in defaultConfigFileName in current directory + const char *env = ::getenv( env_name ) ; + return root_path / (env ? env : default_filename) ; +} + +const fs::path Config::Filename() const +{ + return m_path ; } void Config::Save( ) { - StdioFile file( m_configFile.string(), 0600 ) ; - m_cfg.Write( file ) ; + StdioFile file( m_path.string(), 0600 ) ; + m_file.Write( file ) ; } -Json& Config::Get() +void Config::Set( const std::string& key, const Json& value ) { - return m_cfg ; + m_file.Add( key, value ) ; +} + +Json Config::Get( const std::string& key ) const +{ + return m_cmd.Has(key) ? m_cmd[key] : m_file[key] ; +} + +Json Config::GetAll() const +{ + Json::Object obj = m_file.AsObject() ; + Json::Object cmd_obj = m_cmd.AsObject() ; + + for ( Json::Object::iterator i = cmd_obj.begin() ; i != cmd_obj.end() ; ++i ) + obj[i->first] = i->second ; + + return Json( obj ) ; } Json Config::Read() { try { - return Json::ParseFile( m_configFile.string() ) ; + return Json::ParseFile( m_path.string() ) ; } catch ( Exception& e ) { diff --git a/libgrive/src/util/Config.hh b/libgrive/src/util/Config.hh index 30ef116..8349ce3 100644 --- a/libgrive/src/util/Config.hh +++ b/libgrive/src/util/Config.hh @@ -23,6 +23,14 @@ #include "FileSystem.hh" #include "protocol/Json.hh" +namespace boost +{ + namespace program_options + { + class variables_map ; + } +} + namespace gr { class Config @@ -31,18 +39,30 @@ public : struct Error : virtual Exception {} ; typedef boost::error_info File ; - Config(const fs::path& configFile) ; + Config( const fs::path& root_path ) ; + Config( const boost::program_options::variables_map& vm ) ; + + const fs::path Filename() const ; - Json& Get() ; + void Set( const std::string& key, const Json& value ) ; + Json Get( const std::string& key ) const ; + + Json GetAll() const ; void Save() ; - const fs::path &ConfigFile() const; private : - Json Read() ; + Json Read( ) ; + static fs::path GetPath( const fs::path& root_path ) ; private : - const fs::path m_configFile; - Json m_cfg ; + //! config file path + fs::path m_path; + + //! config values loaded from config file + Json m_file ; + + //! config values from command line + Json m_cmd ; } ; } // end of namespace diff --git a/libgrive/test/util/ConfigTest.cc b/libgrive/test/util/ConfigTest.cc index 33a427d..94b3eef 100644 --- a/libgrive/test/util/ConfigTest.cc +++ b/libgrive/test/util/ConfigTest.cc @@ -36,22 +36,22 @@ ConfigTest::ConfigTest( ) void ConfigTest::TestInitialiseWithEmptyString( ) { - Config config(""); - GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string()) ; + Config config(""); + GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string()) ; } void ConfigTest::TestInitialiseWithString( ) { - Config config("/home/.grive"); - GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string()) ; + Config config("/home/.grive"); + GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string()) ; } void ConfigTest::TestInitialiseWithFileSystemPath( ) { - fs::path path("/home"); - fs::path file(".grive"); - Config config(path / file); - GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string()); + fs::path path("/home"); + fs::path file(".grive"); + Config config(path / file); + GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string()); }