mirror of https://github.com/vitalif/grive2
refactored the config file part from #109
parent
612b35a090
commit
804fe923f2
|
@ -46,9 +46,6 @@
|
||||||
|
|
||||||
const std::string client_id = "22314510474.apps.googleusercontent.com" ;
|
const std::string client_id = "22314510474.apps.googleusercontent.com" ;
|
||||||
const std::string client_secret = "bl4ufi89h-9MkFlypcI7R785" ;
|
const std::string client_secret = "bl4ufi89h-9MkFlypcI7R785" ;
|
||||||
const std::string defaultRootFolder = ".";
|
|
||||||
const std::string defaultConfigFileName = ".grive";
|
|
||||||
const char *configFileEnvironmentVariable = "GR_CONFIG";
|
|
||||||
|
|
||||||
using namespace gr ;
|
using namespace gr ;
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
@ -105,8 +102,6 @@ int Main( int argc, char **argv )
|
||||||
{
|
{
|
||||||
InitGCrypt() ;
|
InitGCrypt() ;
|
||||||
|
|
||||||
std::string rootFolder = defaultRootFolder;
|
|
||||||
|
|
||||||
// construct the program options
|
// construct the program options
|
||||||
po::options_description desc( "Grive options" );
|
po::options_description desc( "Grive options" );
|
||||||
desc.add_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::store(po::parse_command_line( argc, argv, desc), vm );
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
|
|
||||||
|
// simple commands that doesn't require log or config
|
||||||
if ( vm.count("help") )
|
if ( vm.count("help") )
|
||||||
{
|
{
|
||||||
std::cout << desc << std::endl ;
|
std::cout << desc << std::endl ;
|
||||||
|
@ -144,31 +140,9 @@ int Main( int argc, char **argv )
|
||||||
// initialize logging
|
// initialize logging
|
||||||
InitLog(vm) ;
|
InitLog(vm) ;
|
||||||
|
|
||||||
boost::shared_ptr<Config> config ;
|
Config config(vm) ;
|
||||||
|
|
||||||
// config file will be (in order of preference)
|
Log( "config file name %1%", config.Filename(), log::verbose );
|
||||||
// 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<std::string>();
|
|
||||||
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 );
|
|
||||||
|
|
||||||
if ( vm.count( "auth" ) )
|
if ( vm.count( "auth" ) )
|
||||||
{
|
{
|
||||||
|
@ -188,14 +162,14 @@ int Main( int argc, char **argv )
|
||||||
token.Auth( code ) ;
|
token.Auth( code ) ;
|
||||||
|
|
||||||
// save to config
|
// save to config
|
||||||
config->Get().Add( "refresh_token", Json( token.RefreshToken() ) ) ;
|
config.Set( "refresh_token", Json( token.RefreshToken() ) ) ;
|
||||||
config->Save() ;
|
config.Save() ;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string refresh_token ;
|
std::string refresh_token ;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
refresh_token = config->Get()["refresh_token"].Str() ;
|
refresh_token = config.Get("refresh_token").Str() ;
|
||||||
}
|
}
|
||||||
catch ( Exception& e )
|
catch ( Exception& e )
|
||||||
{
|
{
|
||||||
|
@ -210,7 +184,7 @@ int Main( int argc, char **argv )
|
||||||
OAuth2 token( refresh_token, client_id, client_secret ) ;
|
OAuth2 token( refresh_token, client_id, client_secret ) ;
|
||||||
AuthAgent agent( token, std::auto_ptr<http::Agent>( new http::CurlAgent ) ) ;
|
AuthAgent agent( token, std::auto_ptr<http::Agent>( new http::CurlAgent ) ) ;
|
||||||
|
|
||||||
Drive drive( &agent, options, rootFolder ) ;
|
Drive drive( &agent, config.GetAll() ) ;
|
||||||
drive.DetectChanges() ;
|
drive.DetectChanges() ;
|
||||||
|
|
||||||
if ( vm.count( "dry-run" ) == 0 )
|
if ( vm.count( "dry-run" ) == 0 )
|
||||||
|
@ -221,7 +195,7 @@ int Main( int argc, char **argv )
|
||||||
else
|
else
|
||||||
drive.DryRun() ;
|
drive.DryRun() ;
|
||||||
|
|
||||||
config->Save() ;
|
config.Save() ;
|
||||||
Log( "Finished!", log::info ) ;
|
Log( "Finished!", log::info ) ;
|
||||||
return 0 ;
|
return 0 ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,10 +51,10 @@ namespace
|
||||||
const std::string state_file = ".grive_state" ;
|
const std::string state_file = ".grive_state" ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Drive::Drive( http::Agent *http, const Json& options, const std::string &rootFolder) :
|
Drive::Drive( http::Agent *http, const Json& options ) :
|
||||||
m_http( http ),
|
m_http ( http ),
|
||||||
m_state( fs::path(rootFolder), fs::path(rootFolder) / fs::path(state_file), options ),
|
m_root ( options["path"].Str() ),
|
||||||
m_rootFolder(rootFolder),
|
m_state ( m_root / state_file, options ),
|
||||||
m_options ( options )
|
m_options ( options )
|
||||||
{
|
{
|
||||||
assert( m_http != 0 ) ;
|
assert( m_http != 0 ) ;
|
||||||
|
@ -128,7 +128,7 @@ void Drive::SyncFolders( )
|
||||||
void Drive::DetectChanges()
|
void Drive::DetectChanges()
|
||||||
{
|
{
|
||||||
Log( "Reading local directories", log::info ) ;
|
Log( "Reading local directories", log::info ) ;
|
||||||
m_state.FromLocal( m_rootFolder ) ;
|
m_state.FromLocal( m_root ) ;
|
||||||
|
|
||||||
long prev_stamp = m_state.ChangeStamp() ;
|
long prev_stamp = m_state.ChangeStamp() ;
|
||||||
Trace( "previous change stamp is %1%", prev_stamp ) ;
|
Trace( "previous change stamp is %1%", prev_stamp ) ;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class Entry ;
|
||||||
class Drive
|
class Drive
|
||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
Drive( http::Agent *http, const Json& options, const std::string &rootFolder ) ;
|
Drive( http::Agent *http, const Json& options ) ;
|
||||||
|
|
||||||
void DetectChanges() ;
|
void DetectChanges() ;
|
||||||
void Update() ;
|
void Update() ;
|
||||||
|
@ -59,8 +59,8 @@ private :
|
||||||
private :
|
private :
|
||||||
http::Agent *m_http ;
|
http::Agent *m_http ;
|
||||||
std::string m_resume_link ;
|
std::string m_resume_link ;
|
||||||
|
fs::path m_root ;
|
||||||
State m_state ;
|
State m_state ;
|
||||||
fs::path m_rootFolder;
|
|
||||||
Json m_options ;
|
Json m_options ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
|
@ -58,8 +58,8 @@ const std::string xml_meta =
|
||||||
|
|
||||||
|
|
||||||
/// default constructor creates the root folder
|
/// default constructor creates the root folder
|
||||||
Resource::Resource(const fs::path& rootFolder) :
|
Resource::Resource(const fs::path& root_folder) :
|
||||||
m_name ( rootFolder.string() ),
|
m_name ( root_folder.string() ),
|
||||||
m_kind ( "folder" ),
|
m_kind ( "folder" ),
|
||||||
m_id ( "folder:root" ),
|
m_id ( "folder:root" ),
|
||||||
m_href ( root_href ),
|
m_href ( root_href ),
|
||||||
|
|
|
@ -51,7 +51,7 @@ public :
|
||||||
typedef Children::const_iterator iterator ;
|
typedef Children::const_iterator iterator ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
Resource(const fs::path& rootFolder) ;
|
Resource(const fs::path& root_folder) ;
|
||||||
Resource( const std::string& name, const std::string& kind ) ;
|
Resource( const std::string& name, const std::string& kind ) ;
|
||||||
|
|
||||||
// default copy ctor & op= are fine
|
// default copy ctor & op= are fine
|
||||||
|
|
|
@ -32,9 +32,9 @@
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
State::State( const fs::path& rootFolder, const fs::path& filename, const Json& options ) :
|
State::State( const fs::path& filename, const Json& options ) :
|
||||||
m_res(rootFolder),
|
m_res ( options["path"].Str() ),
|
||||||
m_cstamp( -1 )
|
m_cstamp ( -1 )
|
||||||
{
|
{
|
||||||
Read( filename ) ;
|
Read( filename ) ;
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,7 @@ public :
|
||||||
typedef ResourceTree::iterator iterator ;
|
typedef ResourceTree::iterator iterator ;
|
||||||
|
|
||||||
public :
|
public :
|
||||||
explicit State( const fs::path& rootFolder, const fs::path& filename, const Json& options ) ;
|
explicit State( const fs::path& filename, const Json& options ) ;
|
||||||
~State() ;
|
~State() ;
|
||||||
|
|
||||||
void FromLocal( const fs::path& p ) ;
|
void FromLocal( const fs::path& p ) ;
|
||||||
|
|
|
@ -26,39 +26,80 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
|
||||||
|
namespace po = boost::program_options;
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
Config::Config(const fs::path& configFile) :
|
const std::string default_filename = ".grive";
|
||||||
m_configFile(configFile),
|
const char *env_name = "GR_CONFIG";
|
||||||
m_cfg( Read() )
|
const std::string default_root_folder = ".";
|
||||||
|
|
||||||
|
Config::Config( const fs::path& root_path ) :
|
||||||
|
m_path( GetPath( root_path ) )
|
||||||
{
|
{
|
||||||
if (configFile.empty())
|
m_file = Read() ;
|
||||||
{
|
|
||||||
throw Error() << expt::ErrMsg("Config cannot be initalised with an empty string.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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<std::string>()
|
||||||
|
: 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( )
|
void Config::Save( )
|
||||||
{
|
{
|
||||||
StdioFile file( m_configFile.string(), 0600 ) ;
|
StdioFile file( m_path.string(), 0600 ) ;
|
||||||
m_cfg.Write( file ) ;
|
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()
|
Json Config::Read()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return Json::ParseFile( m_configFile.string() ) ;
|
return Json::ParseFile( m_path.string() ) ;
|
||||||
}
|
}
|
||||||
catch ( Exception& e )
|
catch ( Exception& e )
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,6 +23,14 @@
|
||||||
#include "FileSystem.hh"
|
#include "FileSystem.hh"
|
||||||
#include "protocol/Json.hh"
|
#include "protocol/Json.hh"
|
||||||
|
|
||||||
|
namespace boost
|
||||||
|
{
|
||||||
|
namespace program_options
|
||||||
|
{
|
||||||
|
class variables_map ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace gr {
|
namespace gr {
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
|
@ -31,18 +39,30 @@ public :
|
||||||
struct Error : virtual Exception {} ;
|
struct Error : virtual Exception {} ;
|
||||||
typedef boost::error_info<struct FileTag, std::string> File ;
|
typedef boost::error_info<struct FileTag, std::string> 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() ;
|
void Save() ;
|
||||||
const fs::path &ConfigFile() const;
|
|
||||||
|
|
||||||
private :
|
private :
|
||||||
Json Read() ;
|
Json Read( ) ;
|
||||||
|
static fs::path GetPath( const fs::path& root_path ) ;
|
||||||
|
|
||||||
private :
|
private :
|
||||||
const fs::path m_configFile;
|
//! config file path
|
||||||
Json m_cfg ;
|
fs::path m_path;
|
||||||
|
|
||||||
|
//! config values loaded from config file
|
||||||
|
Json m_file ;
|
||||||
|
|
||||||
|
//! config values from command line
|
||||||
|
Json m_cmd ;
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|
|
@ -36,22 +36,22 @@ ConfigTest::ConfigTest( )
|
||||||
|
|
||||||
void ConfigTest::TestInitialiseWithEmptyString( )
|
void ConfigTest::TestInitialiseWithEmptyString( )
|
||||||
{
|
{
|
||||||
Config config("");
|
Config config("");
|
||||||
GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string()) ;
|
GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigTest::TestInitialiseWithString( )
|
void ConfigTest::TestInitialiseWithString( )
|
||||||
{
|
{
|
||||||
Config config("/home/.grive");
|
Config config("/home/.grive");
|
||||||
GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string()) ;
|
GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string()) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ConfigTest::TestInitialiseWithFileSystemPath( )
|
void ConfigTest::TestInitialiseWithFileSystemPath( )
|
||||||
{
|
{
|
||||||
fs::path path("/home");
|
fs::path path("/home");
|
||||||
fs::path file(".grive");
|
fs::path file(".grive");
|
||||||
Config config(path / file);
|
Config config(path / file);
|
||||||
GRUT_ASSERT_EQUAL( "/home/.grive", config.ConfigFile().string());
|
GRUT_ASSERT_EQUAL( "/home/.grive", config.Filename().string());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue