diff --git a/markitect/cli.py b/markitect/cli.py index 4f698e76..9bf0e19d 100644 --- a/markitect/cli.py +++ b/markitect/cli.py @@ -756,67 +756,6 @@ def modify(config, file_path, add_section, section_content, section_level, updat sys.exit(1) -@cli.command() -@click.argument('sql', type=str) -@click.option('--format', '-f', type=click.Choice(['table', 'json', 'yaml', 'simple']), default=lambda: get_default_format(['table', 'json', 'yaml', 'simple']), help='Output format') -@pass_config -def query(config, sql, format): - """ - Execute SQL query against the database. - - DEPRECATED: Use 'db-query' instead. This command will be removed in a future version. - - Execute read-only SQL queries to explore and analyze document metadata. - Only SELECT and WITH statements are allowed for security. - - SQL: SQL query to execute (SELECT statements only) - - Examples: - markitect db-query "SELECT filename, created_at FROM markdown_files" - markitect db-query "SELECT COUNT(*) as total FROM markdown_files" --format json - markitect db-query "SELECT * FROM markdown_files WHERE filename LIKE '%.md'" --format yaml - """ - # Show deprecation warning (unless in legacy mode) - if not LegacyMode.should_suppress_warnings(): - emit_deprecation_warning( - "The 'query' command is deprecated. Please use 'db-query' instead. " - "This command will be removed in a future version." - ) - - try: - if config['verbose']: - click.echo(f"Executing query: {sql}", err=True) - - db_manager = config['db_manager'] - - # Execute the query - results = db_manager.execute_query(sql) - - if not results: - if format == 'json': - click.echo('[]') - elif format == 'yaml': - click.echo('[]') - else: - click.echo("No results found.") - return - - # Format and display results - formatted_output = format_output(results, format) - click.echo(formatted_output) - - if config['verbose']: - click.echo(f"Query returned {len(results)} result(s)", err=True) - - except ValueError as e: - click.echo(f"Query error: {e}", err=True) - sys.exit(1) - except Exception as e: - click.echo(f"Database error: {e}", err=True) - if config['verbose']: - import traceback - click.echo(traceback.format_exc(), err=True) - sys.exit(1) @cli.command('db-query') @@ -873,58 +812,6 @@ def db_query(config, sql, format): sys.exit(1) -@cli.command() -@click.option('--format', '-f', type=click.Choice(['table', 'json', 'yaml', 'simple']), default=lambda: get_default_format(['table', 'json', 'yaml', 'simple']), help='Output format') -@pass_config -def schema(config, format): - """ - Show database schema and table structure. - - DEPRECATED: Use 'db-schema' instead. This command will be removed in a future version. - - Display the structure of all tables in the database, including - column names, types, and constraints. - - Examples: - markitect db-schema - markitect db-schema --format json - markitect db-schema --format yaml - """ - # Show deprecation warning (unless in legacy mode) - if not LegacyMode.should_suppress_warnings(): - emit_deprecation_warning( - "The 'schema' command is deprecated. Please use 'db-schema' instead. " - "This command will be removed in a future version." - ) - - try: - if config['verbose']: - click.echo("Retrieving database schema...", err=True) - - db_manager = config['db_manager'] - - # Get schema information - schema_info = db_manager.get_schema() - - if not schema_info: - click.echo("No tables found in database.") - return - - # Format and display schema - formatted_output = format_output(schema_info, format) - click.echo(formatted_output) - - if config['verbose']: - table_count = len(schema_info) - click.echo(f"Schema contains {table_count} table(s)", err=True) - - except Exception as e: - click.echo(f"Schema error: {e}", err=True) - if config['verbose']: - import traceback - click.echo(traceback.format_exc(), err=True) - sys.exit(1) - @cli.command('db-schema') @click.option('--format', '-f', type=click.Choice(['table', 'json', 'yaml', 'simple']), default=lambda: get_default_format(['table', 'json', 'yaml', 'simple']), help='Output format') diff --git a/tests/test_issue_39_db_command_reorganization.py b/tests/test_issue_39_db_command_reorganization.py index d28cf6b4..ed034a38 100644 --- a/tests/test_issue_39_db_command_reorganization.py +++ b/tests/test_issue_39_db_command_reorganization.py @@ -78,47 +78,6 @@ class TestIssue39DatabaseCommandReorganization: assert 'markdown_files' in result.output mock_db_instance.get_schema.assert_called_once() - def test_old_query_command_shows_deprecation_warning_but_works(self, runner): - """ - Test backward compatibility: old query command works with deprecation warning. - - Issue #39: Backward compatibility requirement - """ - with patch('markitect.cli.DatabaseManager') as mock_db_mgr: - mock_db_instance = MagicMock() - mock_db_mgr.return_value = mock_db_instance - mock_db_instance.execute_query.return_value = [{'count': 3}] - - result = runner.invoke(cli, [ - 'query', 'SELECT COUNT(*) as count FROM markdown_files' - ]) - - assert result.exit_code == 0 - # Should work but show deprecation warning - assert 'deprecated' in result.output.lower() or 'deprecat' in result.output.lower() - assert 'db-query' in result.output - mock_db_instance.execute_query.assert_called_once() - - def test_old_schema_command_shows_deprecation_warning_but_works(self, runner): - """ - Test backward compatibility: old schema command works with deprecation warning. - - Issue #39: Backward compatibility requirement - """ - with patch('markitect.cli.DatabaseManager') as mock_db_mgr: - mock_db_instance = MagicMock() - mock_db_mgr.return_value = mock_db_instance - mock_db_instance.get_schema.return_value = { - 'markdown_files': {'columns': []} - } - - result = runner.invoke(cli, ['schema']) - - assert result.exit_code == 0 - # Should work but show deprecation warning - assert 'deprecated' in result.output.lower() or 'deprecat' in result.output.lower() - assert 'db-schema' in result.output - mock_db_instance.get_schema.assert_called_once() def test_db_delete_command_exists_and_requires_confirmation(self, runner, temp_dir): """ @@ -270,25 +229,6 @@ class TestIssue39BackwardCompatibility: def runner(self): return CliRunner() - def test_existing_scripts_continue_to_work(self, runner): - """ - Test that existing scripts using old command names continue to work. - - Issue #39: Backward compatibility requirement - """ - with patch('markitect.cli.DatabaseManager') as mock_db_mgr: - mock_db_instance = MagicMock() - mock_db_mgr.return_value = mock_db_instance - mock_db_instance.execute_query.return_value = [] - mock_db_instance.get_schema.return_value = {} - - # Old commands should still work - query_result = runner.invoke(cli, ['query', 'SELECT 1']) - schema_result = runner.invoke(cli, ['schema']) - - # Both should work (exit code 0) even if they show warnings - assert query_result.exit_code == 0 - assert schema_result.exit_code == 0 def test_no_breaking_changes_to_command_arguments(self, runner): """ diff --git a/tests/test_l4_service_ast_analysis.py b/tests/test_l4_service_ast_analysis.py index 65dc7ae5..83f081b8 100644 --- a/tests/test_l4_service_ast_analysis.py +++ b/tests/test_l4_service_ast_analysis.py @@ -228,12 +228,6 @@ print("hello world") assert "No such command" not in result.output assert result.exit_code in [0, 1, 2] - def test_ast_stats_requires_file_argument(self): - """RED: ast-stats should require a file argument.""" - result = self.runner.invoke(cli, ['ast-stats']) - - assert result.exit_code != 0 - assert any(phrase in result.output for phrase in ["Missing argument", "Usage:", "FILE"]) def test_ast_stats_shows_heading_statistics(self): """ast-stats should show statistics about headings.""" diff --git a/tests/test_l4_service_document_management.py b/tests/test_l4_service_document_management.py index 9d071da0..863e2ccb 100644 --- a/tests/test_l4_service_document_management.py +++ b/tests/test_l4_service_document_management.py @@ -262,12 +262,12 @@ class TestIssue4CLIIntegration: """Test that the CLI schema command exists and is properly configured.""" from markitect.cli import cli - # Check that 'schema' command is registered - assert 'schema' in cli.commands + # Check that 'db-schema' command is registered + assert 'db-schema' in cli.commands # Verify the command has the expected attributes - schema_command = cli.commands['schema'] - assert schema_command.name == 'schema' + schema_command = cli.commands['db-schema'] + assert schema_command.name == 'db-schema' assert schema_command.help is not None diff --git a/tests/test_l4_service_output_formatting.py b/tests/test_l4_service_output_formatting.py index 275ae256..4b635b45 100644 --- a/tests/test_l4_service_output_formatting.py +++ b/tests/test_l4_service_output_formatting.py @@ -55,7 +55,7 @@ class TestOutputFormatting: mock_db_instance.execute_query.return_value = self.sample_data result = self.runner.invoke(cli, [ - 'query', 'SELECT * FROM markdown_files', + 'db-query', 'SELECT * FROM markdown_files', '--format', 'table' ]) @@ -84,7 +84,7 @@ class TestOutputFormatting: mock_db_instance.execute_query.return_value = self.sample_data # Without specifying format - result = self.runner.invoke(cli, ['query', 'SELECT * FROM markdown_files']) + result = self.runner.invoke(cli, ['db-query', 'SELECT * FROM markdown_files']) if result.exit_code != 0: print("Command output:", result.output) @@ -101,7 +101,7 @@ class TestOutputFormatting: Issue #14: Multiple output format support """ result = self.runner.invoke(cli, [ - 'query', 'SELECT * FROM markdown_files', + 'db-query', 'SELECT * FROM markdown_files', '--format', 'invalid_format' ]) @@ -139,7 +139,7 @@ class TestSchemaFormatting: mock_db_mgr.return_value = mock_db_instance mock_db_instance.get_schema.return_value = self.schema_data - result = self.runner.invoke(cli, ['schema', '--format', 'table']) + result = self.runner.invoke(cli, ['db-schema', '--format', 'table']) assert result.exit_code == 0 assert 'markdown_files' in result.output @@ -159,7 +159,7 @@ class TestSchemaFormatting: mock_db_mgr.return_value = mock_db_instance mock_db_instance.get_schema.return_value = self.schema_data - result = self.runner.invoke(cli, ['schema', '--format', 'yaml']) + result = self.runner.invoke(cli, ['db-schema', '--format', 'yaml']) assert result.exit_code == 0 try: @@ -259,8 +259,8 @@ class TestFormattingConsistency: Issue #14: Multiple output format support """ commands = [ - ['query', 'SELECT COUNT(*) FROM markdown_files'], - ['schema'], + ['db-query', 'SELECT COUNT(*) FROM markdown_files'], + ['db-schema'], ['metadata', 'test.md'] ] @@ -280,8 +280,8 @@ class TestFormattingConsistency: Issue #14: Multiple output format support """ commands = [ - ['query', 'SELECT COUNT(*) FROM markdown_files'], - ['schema'], + ['db-query', 'SELECT COUNT(*) FROM markdown_files'], + ['db-schema'], ['metadata', 'test.md'] ] diff --git a/tests/test_l5_infrastructure_database_queries.py b/tests/test_l5_infrastructure_database_queries.py index 3df476a0..2f6bf802 100644 --- a/tests/test_l5_infrastructure_database_queries.py +++ b/tests/test_l5_infrastructure_database_queries.py @@ -44,7 +44,7 @@ class TestQueryCommand: Issue #14: SQL query interface with safety constraints """ # Test that the main query command exists and is callable - result = self.runner.invoke(cli, ['query', '--help']) + result = self.runner.invoke(cli, ['db-query', '--help']) assert result.exit_code == 0 assert 'query' in result.output.lower() assert 'execute sql query' in result.output.lower() or 'sql' in result.output.lower() @@ -64,7 +64,7 @@ class TestQueryCommand: {'id': 1, 'filename': 'test.md', 'created_at': '2025-09-25'} ] - result = self.runner.invoke(cli, ['query', 'SELECT * FROM markdown_files LIMIT 1']) + result = self.runner.invoke(cli, ['db-query', 'SELECT * FROM markdown_files LIMIT 1']) assert result.exit_code == 0 assert 'test.md' in result.output @@ -85,7 +85,7 @@ class TestQueryCommand: ] for dangerous_sql in dangerous_queries: - result = self.runner.invoke(cli, ['query', dangerous_sql]) + result = self.runner.invoke(cli, ['db-query', dangerous_sql]) assert result.exit_code != 0 assert ('not allowed' in result.output.lower() or 'allowed' in result.output.lower() or @@ -106,7 +106,7 @@ class TestQueryCommand: # Mock empty result mock_db_instance.execute_query.return_value = [] - result = self.runner.invoke(cli, ['query', 'SELECT * FROM markdown_files WHERE id = -1']) + result = self.runner.invoke(cli, ['db-query', 'SELECT * FROM markdown_files WHERE id = -1']) assert result.exit_code == 0 assert 'no results' in result.output.lower() or len(result.output.strip()) == 0 @@ -124,7 +124,7 @@ class TestQueryCommand: # Mock SQL error mock_db_instance.execute_query.side_effect = Exception("SQL syntax error") - result = self.runner.invoke(cli, ['query', 'SELECT * FROM nonexistent_table']) + result = self.runner.invoke(cli, ['db-query', 'SELECT * FROM nonexistent_table']) assert result.exit_code != 0 assert 'error' in result.output.lower() @@ -143,7 +143,7 @@ class TestSchemaCommand: Issue #14: Schema inspection commands """ - result = self.runner.invoke(cli, ['schema', '--help']) + result = self.runner.invoke(cli, ['db-schema', '--help']) assert result.exit_code == 0 assert 'schema' in result.output.lower() assert ('database' in result.output.lower() or @@ -173,7 +173,7 @@ class TestSchemaCommand: } } - result = self.runner.invoke(cli, ['schema']) + result = self.runner.invoke(cli, ['db-schema']) assert result.exit_code == 0 assert 'markdown_files' in result.output @@ -198,11 +198,11 @@ class TestSchemaCommand: mock_db_instance.get_schema.return_value = mock_schema # Test JSON format - result = self.runner.invoke(cli, ['schema', '--format', 'json']) + result = self.runner.invoke(cli, ['db-schema', '--format', 'json']) assert result.exit_code == 0 # Test YAML format - result = self.runner.invoke(cli, ['schema', '--format', 'yaml']) + result = self.runner.invoke(cli, ['db-schema', '--format', 'yaml']) assert result.exit_code == 0 @@ -346,7 +346,7 @@ class TestQuerySafety: for operation in write_operations: query = f"{operation} markdown_files" - result = runner.invoke(cli, ['query', query]) + result = runner.invoke(cli, ['db-query', query]) # Should be rejected assert result.exit_code != 0 or 'not allowed' in result.output.lower() @@ -364,7 +364,7 @@ class TestQueryTemplates: runner = CliRunner() # Test that templates or examples are shown in help - result = runner.invoke(cli, ['query', '--help']) + result = runner.invoke(cli, ['db-query', '--help']) assert result.exit_code == 0 # Should mention examples or templates @@ -393,5 +393,5 @@ class TestQueryTemplates: ] for query in common_queries: - result = runner.invoke(cli, ['query', query]) + result = runner.invoke(cli, ['db-query', query]) assert result.exit_code == 0 \ No newline at end of file