Commit d5617f42 authored by Laurent Bachelier's avatar Laurent Bachelier

Add Config plugin (configuration management from the CLI)

All CLI commands are under the 'config' namespace since they should not
be used often; shortcuts and dedicated commands should exist for
day-to-day operations.

The 'resolve' command has been moved to that plugin, and a config list
has been implemented (now only for the global config).

Tests have been added for both commands.
parent 050a6e01
# -*- coding: utf-8 -*-
# Copyright (C) 2011 Romain Bignon, Laurent Bachelier
#
# This file is part of ass2m.
#
# ass2m is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# ass2m is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with ass2m. If not, see <http://www.gnu.org/licenses/>.
import os
import sys
from ass2m.plugin import Plugin
from ass2m.cmd import Command
__all__ = ['ConfigPlugin']
class ResolveCmd(Command):
DESCRIPTION = 'Get the storage name of a path'
@staticmethod
def configure_parser(parser):
parser.add_argument('path', nargs='+')
def cmd(self, args):
for path in args.path:
if not os.path.exists(path):
print >>sys.stderr, 'Error: Path "%s" does not exist.' % path
continue
f = self.storage.get_file_from_realpath(os.path.realpath(path))
if not f:
print >>sys.stderr, 'Error: Path "%s" is not in working directory.' % path
continue
print '%s => %s' % (f.path, os.path.join(self.storage.path, f._get_confname()))
class ListConfigCmd(Command):
DESCRIPTION = 'Get all the values of the global config'
def cmd(self, args):
c = self.storage.get_config()
self._print_config(c.data)
def _print_config(self, data):
for sectionkey, section in data.iteritems():
for key, value in section.iteritems():
print "%s.%s=%s" % (sectionkey, key, value)
class ConfigPlugin(Plugin):
def init(self):
self.register_cli_command('config', 'Interact with the stored configurations')
self.register_cli_command('config', 'resolve', ResolveCmd)
self.register_cli_command('config', 'global', 'list', ListConfigCmd)
......@@ -162,25 +162,6 @@ class ChModCmd(Command):
f.perms[args.who] = (perms & ~to_remove) | to_add
f.save()
class ResolveCmd(Command):
DESCRIPTION = 'Get the storage name of a path'
@staticmethod
def configure_parser(parser):
parser.add_argument('path', nargs='+')
def cmd(self, args):
for path in args.path:
if not os.path.exists(path):
print >>sys.stderr, 'Error: Path "%s" does not exist.' % path
continue
f = self.storage.get_file_from_realpath(os.path.realpath(path))
if not f:
print >>sys.stderr, 'Error: Path "%s" is not in working directory.' % path
continue
print '%s => %s' % (f.path, os.path.join(self.storage.path, f._get_confname()))
class DownloadAction(ViewAction):
def get(self):
......@@ -211,7 +192,6 @@ class CorePlugin(Plugin):
self.register_cli_command('tree', TreeCmd)
self.register_cli_command('chmod', ChModCmd)
self.register_cli_command('chview', ChViewCmd)
self.register_cli_command('resolve', ResolveCmd)
self.register_web_view(
View(object_type='file', name='raw'),
......
from unittest import TestCase
from ass2m.cli import CLI
from ass2m.storage import Storage
from tempfile import mkdtemp
import os
import shutil
import sys
from StringIO import StringIO
class ConfigCLITest(TestCase):
def setUp(self):
self.root = mkdtemp(prefix='ass2m_test_root')
Storage.create(self.root)
self.app = CLI(self.root)
os.mkdir(os.path.join(self.root, 'penguins'))
with open(os.path.join(self.root, 'penguins', 'gentoo'), 'w') as f:
f.write('HELLO')
def tearDown(self):
if self.root:
shutil.rmtree(self.root)
def beginCapture(self):
self.stdout = sys.stdout
# begin capture
sys.stdout = StringIO()
def endCapture(self):
captured = sys.stdout
# end capture
sys.stdout = self.stdout
self.stdout = None
return captured.getvalue()
def test_resolve(self):
for p in (os.path.join(self.root, 'penguins'), os.path.join(self.root, 'penguins'+os.path.sep)):
self.beginCapture()
assert self.app.main(['ass2m_test', 'config', 'resolve', p]) in (0, None)
output = self.endCapture()
assert output.startswith('/penguins => ')
assert output.strip().endswith('/7fe0243160cdd4fdb87ab2ce1ecf9fef501cd1a5')
self.beginCapture()
assert self.app.main(['ass2m_test', 'config', 'resolve', os.path.join(self.root, 'penguins', 'gentoo')]) in (0, None)
output = self.endCapture()
assert output.startswith('/penguins/gentoo => ')
assert output.strip().endswith('/090ec30f855081df160d60cbfe635c399b5ff523')
self.beginCapture()
assert self.app.main(['ass2m_test', 'config', 'resolve', self.root]) in (0, None)
output = self.endCapture()
assert output.startswith(' => ')
assert output.strip().endswith('/da39a3ee5e6b4b0d3255bfef95601890afd80709')
def test_configList(self):
self.beginCapture()
assert self.app.main(['ass2m_test', 'config', 'global', 'list']) in (0, None)
output = self.endCapture()
assert len(output) == 0
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment