mirror of
https://github.com/valitydev/thrift.git
synced 2024-11-07 02:45:22 +00:00
Thrift-THRIFT-2574: Compiler option to generate namespace directories for Ruby
Client: rb Patch: Andrew Bloomgarden Adds option to generate namespaced ruby classes. Github: closes #140
This commit is contained in:
parent
c9bdd50270
commit
bf2617ed15
@ -82,6 +82,7 @@ class t_rb_generator : public t_oop_generator {
|
||||
out_dir_base_ = "gen-rb";
|
||||
|
||||
require_rubygems_ = (parsed_options.find("rubygems") != parsed_options.end());
|
||||
namespaced_ = (parsed_options.find("namespaced") != parsed_options.end());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -201,7 +202,7 @@ class t_rb_generator : public t_oop_generator {
|
||||
std::string function_signature(t_function* tfunction, std::string prefix="");
|
||||
std::string argument_list(t_struct* tstruct);
|
||||
std::string type_to_enum(t_type* ttype);
|
||||
|
||||
std::string rb_namespace_to_path_prefix(std::string rb_namespace);
|
||||
|
||||
|
||||
std::vector<std::string> ruby_modules(t_program* p) {
|
||||
@ -238,8 +239,14 @@ class t_rb_generator : public t_oop_generator {
|
||||
t_rb_ofstream f_consts_;
|
||||
t_rb_ofstream f_service_;
|
||||
|
||||
std::string namespace_dir_;
|
||||
std::string require_prefix_;
|
||||
|
||||
/** If true, add a "require 'rubygems'" line to the top of each gen-rb file. */
|
||||
bool require_rubygems_;
|
||||
|
||||
/** If true, generate files in idiomatic namespaced directories. */
|
||||
bool namespaced_;
|
||||
};
|
||||
|
||||
|
||||
@ -250,14 +257,31 @@ class t_rb_generator : public t_oop_generator {
|
||||
* @param tprogram The program to generate
|
||||
*/
|
||||
void t_rb_generator::init_generator() {
|
||||
string subdir = get_out_dir();
|
||||
|
||||
// Make output directory
|
||||
MKDIR(get_out_dir().c_str());
|
||||
MKDIR(subdir.c_str());
|
||||
|
||||
if (namespaced_) {
|
||||
require_prefix_ = rb_namespace_to_path_prefix(program_->get_namespace("rb"));
|
||||
|
||||
string dir = require_prefix_;
|
||||
string::size_type loc;
|
||||
|
||||
while ((loc = dir.find("/")) != string::npos) {
|
||||
subdir = subdir + dir.substr(0, loc) + "/";
|
||||
MKDIR(subdir.c_str());
|
||||
dir = dir.substr(loc+1);
|
||||
}
|
||||
}
|
||||
|
||||
namespace_dir_ = subdir;
|
||||
|
||||
// Make output file
|
||||
string f_types_name = get_out_dir()+underscore(program_name_)+"_types.rb";
|
||||
string f_types_name = namespace_dir_+underscore(program_name_)+"_types.rb";
|
||||
f_types_.open(f_types_name.c_str());
|
||||
|
||||
string f_consts_name = get_out_dir()+underscore(program_name_)+"_constants.rb";
|
||||
string f_consts_name = namespace_dir_+underscore(program_name_)+"_constants.rb";
|
||||
f_consts_.open(f_consts_name.c_str());
|
||||
|
||||
// Print header
|
||||
@ -268,7 +292,7 @@ void t_rb_generator::init_generator() {
|
||||
|
||||
f_consts_ <<
|
||||
rb_autogen_comment() << endl << render_require_thrift() <<
|
||||
"require '" << underscore(program_name_) << "_types'" << endl <<
|
||||
"require '" << require_prefix_ << underscore(program_name_) << "_types'" << endl <<
|
||||
endl;
|
||||
begin_namespace(f_consts_, ruby_modules(program_));
|
||||
|
||||
@ -292,7 +316,10 @@ string t_rb_generator::render_includes() {
|
||||
const vector<t_program*>& includes = program_->get_includes();
|
||||
string result = "";
|
||||
for (size_t i = 0; i < includes.size(); ++i) {
|
||||
result += "require '" + underscore(includes[i]->get_name()) + "_types'\n";
|
||||
t_program* included = includes[i];
|
||||
std::string included_require_prefix = rb_namespace_to_path_prefix(included->get_namespace("rb"));
|
||||
std::string included_name = included->get_name();
|
||||
result += "require '" + included_require_prefix + underscore(included_name) + "_types'\n";
|
||||
}
|
||||
if (includes.size() > 0) {
|
||||
result += "\n";
|
||||
@ -728,7 +755,7 @@ void t_rb_generator::end_namespace(t_rb_ofstream& out, vector<std::string> modul
|
||||
* @param tservice The service definition
|
||||
*/
|
||||
void t_rb_generator::generate_service(t_service* tservice) {
|
||||
string f_service_name = get_out_dir()+underscore(service_name_)+".rb";
|
||||
string f_service_name = namespace_dir_+underscore(service_name_)+".rb";
|
||||
f_service_.open(f_service_name.c_str());
|
||||
|
||||
f_service_ <<
|
||||
@ -736,11 +763,11 @@ void t_rb_generator::generate_service(t_service* tservice) {
|
||||
|
||||
if (tservice->get_extends() != NULL) {
|
||||
f_service_ <<
|
||||
"require '" << underscore(tservice->get_extends()->get_name()) << "'" << endl;
|
||||
"require '" << require_prefix_ << underscore(tservice->get_extends()->get_name()) << "'" << endl;
|
||||
}
|
||||
|
||||
f_service_ <<
|
||||
"require '" << underscore(program_name_) << "_types'" << endl <<
|
||||
"require '" << require_prefix_ << underscore(program_name_) << "_types'" << endl <<
|
||||
endl;
|
||||
|
||||
begin_namespace(f_service_, ruby_modules(tservice->get_program()));
|
||||
@ -1138,6 +1165,22 @@ string t_rb_generator::type_to_enum(t_type* type) {
|
||||
throw "INVALID TYPE IN type_to_enum: " + type->get_name();
|
||||
}
|
||||
|
||||
string t_rb_generator::rb_namespace_to_path_prefix(string rb_namespace) {
|
||||
string namespaces_left = rb_namespace;
|
||||
string::size_type loc;
|
||||
|
||||
string path_prefix = "";
|
||||
|
||||
while ((loc = namespaces_left.find(".")) != string::npos) {
|
||||
path_prefix = path_prefix + underscore(namespaces_left.substr(0, loc)) + "/";
|
||||
namespaces_left = namespaces_left.substr(loc+1);
|
||||
}
|
||||
if (namespaces_left.size() > 0) {
|
||||
path_prefix = path_prefix + underscore(namespaces_left) + "/";
|
||||
}
|
||||
return path_prefix;
|
||||
}
|
||||
|
||||
|
||||
void t_rb_generator::generate_rdoc(t_rb_ofstream& out, t_doc* tdoc) {
|
||||
if (tdoc->has_doc()) {
|
||||
@ -1221,4 +1264,5 @@ void t_rb_generator::generate_rb_union_validator(t_rb_ofstream& out,
|
||||
}
|
||||
|
||||
THRIFT_REGISTER_GENERATOR(rb, "Ruby",
|
||||
" rubygems: Add a \"require 'rubygems'\" line to the top of each generated file.\n")
|
||||
" rubygems: Add a \"require 'rubygems'\" line to the top of each generated file.\n"
|
||||
" namespaced: Generate files in idiomatic namespaced directories.\n")
|
||||
|
@ -38,13 +38,18 @@ RSpec::Core::RakeTask.new(:'spec:rcov') do |t|
|
||||
end
|
||||
|
||||
desc 'Compile the .thrift files for the specs'
|
||||
task :'gen-rb' => [:'gen-rb:spec', :'gen-rb:benchmark', :'gen-rb:debug_proto']
|
||||
task :'gen-rb' => [:'gen-rb:spec', :'gen-rb:namespaced_spec', :'gen-rb:benchmark', :'gen-rb:debug_proto']
|
||||
namespace :'gen-rb' do
|
||||
task :'spec' do
|
||||
dir = File.dirname(__FILE__) + '/spec'
|
||||
sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/ThriftSpec.thrift"
|
||||
end
|
||||
|
||||
task :'namespaced_spec' do
|
||||
dir = File.dirname(__FILE__) + '/spec'
|
||||
sh THRIFT, '--gen', 'rb:namespaced', '-recurse', '-o', dir, "#{dir}/ThriftNamespacedSpec.thrift"
|
||||
end
|
||||
|
||||
task :'benchmark' do
|
||||
dir = File.dirname(__FILE__) + '/benchmark'
|
||||
sh THRIFT, '--gen', 'rb', '-o', dir, "#{dir}/Benchmark.thrift"
|
||||
|
44
lib/rb/spec/Referenced.thrift
Normal file
44
lib/rb/spec/Referenced.thrift
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
namespace rb OtherNamespace
|
||||
|
||||
enum SomeEnum {
|
||||
ONE
|
||||
TWO
|
||||
}
|
53
lib/rb/spec/ThriftNamespacedSpec.thrift
Normal file
53
lib/rb/spec/ThriftNamespacedSpec.thrift
Normal file
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
namespace rb NamespacedSpecNamespace
|
||||
|
||||
include "Referenced.thrift"
|
||||
|
||||
struct Hello {
|
||||
1: string greeting = "hello world"
|
||||
}
|
||||
|
||||
service NamespacedNonblockingService {
|
||||
Hello greeting(1:bool english)
|
||||
bool block()
|
||||
oneway void unblock(1:i32 n)
|
||||
oneway void shutdown()
|
||||
void sleep(1:double seconds)
|
||||
}
|
62
lib/rb/spec/namespaced_spec.rb
Normal file
62
lib/rb/spec/namespaced_spec.rb
Normal file
@ -0,0 +1,62 @@
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
#
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe 'namespaced generation' do
|
||||
before do
|
||||
require 'namespaced_spec_namespace/namespaced_nonblocking_service'
|
||||
end
|
||||
|
||||
it "generated the right files" do
|
||||
prefix = File.expand_path("../gen-rb", __FILE__)
|
||||
["namespaced_spec_namespace/namespaced_nonblocking_service.rb",
|
||||
"namespaced_spec_namespace/thrift_namespaced_spec_constants.rb",
|
||||
"namespaced_spec_namespace/thrift_namespaced_spec_types.rb",
|
||||
"other_namespace/referenced_constants.rb",
|
||||
"other_namespace/referenced_types.rb"
|
||||
].each do |name|
|
||||
File.exist?(File.join(prefix, name)).should be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "did not generate the wrong files" do
|
||||
prefix = File.expand_path("../gen-rb", __FILE__)
|
||||
["namespaced_nonblocking_service.rb",
|
||||
"thrift_namespaced_spec_constants.rb",
|
||||
"thrift_namespaced_spec_types.rb",
|
||||
"referenced_constants.rb",
|
||||
"referenced_types.rb"
|
||||
].each do |name|
|
||||
File.exist?(File.join(prefix, name)).should_not be_true
|
||||
end
|
||||
end
|
||||
|
||||
it "has a service class in the right place" do
|
||||
defined?(NamespacedSpecNamespace::NamespacedNonblockingService).should be_true
|
||||
end
|
||||
|
||||
it "has a struct in the right place" do
|
||||
defined?(NamespacedSpecNamespace::Hello).should be_true
|
||||
end
|
||||
|
||||
it "required an included file" do
|
||||
defined?(OtherNamespace::SomeEnum).should be_true
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user