wxruby3 0.9.5 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/INSTALL.md +440 -84
  3. data/README.md +40 -23
  4. data/ext/mkrf_conf_ext.rb +68 -0
  5. data/lib/wx/core/ext.rb +22 -3
  6. data/lib/wx/core/secret_store.rb +38 -0
  7. data/lib/wx/doc/extra/02_lifecycles.md +4 -4
  8. data/lib/wx/doc/extra/14_config.md +1 -1
  9. data/lib/wx/doc/secret_store.rb +55 -0
  10. data/lib/wx/version.rb +1 -1
  11. data/lib/wx/wxruby/base.rb +8 -8
  12. data/lib/wx/wxruby/cmd/check.rb +182 -0
  13. data/lib/wx/wxruby/cmd/sampler.rb +39 -29
  14. data/lib/wx/wxruby/cmd/setup.rb +125 -0
  15. data/lib/wx/wxruby/cmd/test.rb +56 -6
  16. data/rakelib/bin.rake +48 -0
  17. data/rakelib/bin.rb +62 -0
  18. data/rakelib/build.rb +11 -7
  19. data/rakelib/config.rake +3 -1
  20. data/rakelib/configure.rb +63 -35
  21. data/rakelib/doc.rake +3 -1
  22. data/rakelib/gem.rake +199 -0
  23. data/rakelib/gem.rb +334 -0
  24. data/rakelib/install.rb +5 -3
  25. data/rakelib/lib/config/{cygwin.rb → freebsd.rb} +1 -1
  26. data/rakelib/lib/config/linux.rb +26 -2
  27. data/rakelib/lib/config/macosx.rb +58 -11
  28. data/rakelib/lib/config/mingw.rb +134 -10
  29. data/rakelib/lib/config/pkgman/linux.rb +144 -0
  30. data/rakelib/lib/config/pkgman/macosx.rb +122 -0
  31. data/rakelib/lib/config/unixish.rb +47 -20
  32. data/rakelib/lib/config/{netbsd.rb → unknown.rb} +3 -2
  33. data/rakelib/lib/config.rb +301 -88
  34. data/rakelib/lib/core/package.rb +47 -49
  35. data/rakelib/lib/director/aui_manager.rb +1 -1
  36. data/rakelib/lib/director/dialog.rb +8 -0
  37. data/rakelib/lib/director/gdicommon.rb +1 -2
  38. data/rakelib/lib/director/grid_ctrl.rb +2 -2
  39. data/rakelib/lib/director/richtext_composite_object.rb +2 -4
  40. data/rakelib/lib/director/secret_store.rb +117 -0
  41. data/rakelib/lib/director/tree_event.rb +2 -2
  42. data/rakelib/lib/generate/doc/secret_store.yaml +55 -0
  43. data/rakelib/lib/generate/doc.rb +29 -14
  44. data/rakelib/lib/generate/interface.rb +4 -2
  45. data/rakelib/lib/specs/interfaces.rb +1 -0
  46. data/rakelib/lib/swig_runner.rb +11 -11
  47. data/rakelib/lib/typemap/common.rb +10 -0
  48. data/rakelib/prepost.rake +17 -5
  49. data/rakelib/yard/templates/default/fulldoc/html/css/wxruby3.css +18 -0
  50. data/rakelib/yard/templates/default/fulldoc/html/setup.rb +5 -5
  51. data/rakelib/yard/yard/relative_markdown_links.rb +7 -1
  52. data/samples/sampler/sample.rb +2 -0
  53. data/tests/lib/wxapp_runner.rb +1 -1
  54. data/tests/test_config.rb +7 -4
  55. data/tests/test_secret_store.rb +83 -0
  56. metadata +46 -23
  57. data/ext/mkrf_conf_srcgem.rb +0 -67
  58. data/rakelib/run.rake +0 -52
@@ -212,6 +212,14 @@ module WXRuby3
212
212
  return Qfalse;
213
213
  }
214
214
  __HEREDOC
215
+ when 'wxSymbolPickerDialog'
216
+ # redefine these to prevent problematic handling of title/caption defaults
217
+ spec.ignore 'wxSymbolPickerDialog::wxSymbolPickerDialog(const wxString &, const wxString &, const wxString &, wxWindow *, wxWindowID, const wxString &, const wxPoint &, const wxSize &, long)',
218
+ 'wxSymbolPickerDialog::Create',
219
+ ignore_doc: false
220
+ spec.extend_interface 'wxSymbolPickerDialog',
221
+ 'wxSymbolPickerDialog(const wxString &symbol, const wxString &initialFont, const wxString &normalTextFont, wxWindow *parent, wxWindowID id, const wxString &title, const wxPoint &pos, const wxSize &size, long style)',
222
+ 'bool Create(const wxString &symbol, const wxString &initialFont, const wxString &normalTextFont, wxWindow *parent, wxWindowID id, const wxString &caption, const wxPoint &pos, const wxSize &size, long style)'
215
223
  when 'wxWizard'
216
224
  # special handling
217
225
  spec.ignore 'wxWizard::GetBitmap'
@@ -52,8 +52,7 @@ module WXRuby3
52
52
  if Config.instance.wx_version >= '3.3.0'
53
53
  # ignore these as they are supposed to specify unary minus but confuse
54
54
  # SWIG
55
- spec.ignore 'wxPoint::operator-(const wxPoint&)',
56
- 'wxRealPoint::operator-(const wxRealPoint&)'
55
+ spec.ignore 'wxPoint::operator-(const wxPoint&)'
57
56
  end
58
57
  spec.regard 'wxRect::Offset', regard_doc: false
59
58
  # overrule common wxPoint mapping for wxRect ctor to fix ctor ambiguities here wrt wxSize
@@ -237,9 +237,9 @@ module WXRuby3
237
237
  static const rb_data_type_t __wxGridWindow_type = {
238
238
  "GridWindow",
239
239
  #if RUBY_API_VERSION_MAJOR >= 3
240
- { NULL, NULL, __wxGridWindow_size, 0, 0},
240
+ { NULL, NULL, __wxGridWindow_size, 0, {}},
241
241
  #else
242
- { NULL, NULL, __wxGridWindow_size, 0},
242
+ { NULL, NULL, __wxGridWindow_size, {}},
243
243
  #endif
244
244
  NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
245
245
  };
@@ -93,9 +93,9 @@ module WXRuby3
93
93
  static const rb_data_type_t __wxRichTextFloatCollector_type = {
94
94
  "RichTextFloatCollector",
95
95
  #if RUBY_API_VERSION_MAJOR >= 3
96
- { NULL, NULL, __wxRichTextFloatCollector_size, 0, 0},
96
+ { NULL, NULL, __wxRichTextFloatCollector_size, 0, {}},
97
97
  #else
98
- { NULL, NULL, __wxRichTextFloatCollector_size, 0},
98
+ { NULL, NULL, __wxRichTextFloatCollector_size, {}},
99
99
  #endif
100
100
  NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
101
101
  };
@@ -177,12 +177,10 @@ module WXRuby3
177
177
  {
178
178
  VALUE rc = Qnil;
179
179
  const wxRichTextLineVector &lines = $self->GetLines();
180
- int lnr = 0;
181
180
  for (const wxRichTextLine* line : lines)
182
181
  {
183
182
  VALUE rb_ln = SWIG_NewPointerObj(SWIG_as_voidptr(const_cast<wxRichTextLine*> (line)), SWIGTYPE_p_wxRichTextLine, 0);
184
183
  rc = rb_yield(rb_ln);
185
- ++lnr;
186
184
  }
187
185
  return rc;
188
186
  }
@@ -0,0 +1,117 @@
1
+ # Copyright (c) 2023 M.J.N. Corino, The Netherlands
2
+ #
3
+ # This software is released under the MIT license.
4
+
5
+ ###
6
+ # wxRuby3 wxWidgets interface director
7
+ ###
8
+
9
+ module WXRuby3
10
+
11
+ class Director
12
+
13
+ class SecretStore < Director
14
+
15
+ def setup
16
+ super
17
+ spec.items << 'wxSecretValue'
18
+ spec.gc_as_untracked # don't even track SecretStore and SecretValue objects
19
+ # there is no possibility of SecretStore derivatives
20
+ # not least because wxRuby only ever allows a single global SecretStore
21
+ spec.disable_proxies
22
+ spec.make_abstract 'wxSecretStore'
23
+
24
+ spec.include 'ruby/encoding.h'
25
+
26
+ spec.ignore 'wxSecretValue::GetAsString',
27
+ 'wxSecretValue::GetSize',
28
+ 'wxSecretValue::GetData',
29
+ 'wxSecretValue::Wipe',
30
+ 'wxSecretValue::WipeString',
31
+ 'wxSecretValue::wxSecretValue(const wxString&)',
32
+ 'wxSecretValue::wxSecretValue(size_t, const void *)'
33
+ spec.regard 'wxSecretValue::wxSecretValue()',
34
+ 'wxSecretValue::wxSecretValue(const wxSecretValue&)',
35
+ regard_doc: false
36
+ # customize string arg ctor
37
+ spec.add_extend_code 'wxSecretValue', <<~__HEREDOC
38
+ wxSecretValue(VALUE secret_string)
39
+ {
40
+ if (RTEST(secret_string) && TYPE(secret_string) == T_STRING)
41
+ {
42
+ if (ENCODING_GET(secret_string) == rb_utf8_encindex())
43
+ {
44
+ return new wxSecretValue(RSTR_TO_WXSTR(secret_string));
45
+ }
46
+ else
47
+ {
48
+ return new wxSecretValue(RSTRING_LEN(secret_string), (void*)StringValuePtr(secret_string));
49
+ }
50
+ }
51
+ else
52
+ {
53
+ rb_raise(rb_eArgError, "Expected String or Wx::SecretValue for #0");
54
+ }
55
+ }
56
+ __HEREDOC
57
+
58
+ # customize GetData
59
+ spec.map 'const void*' => 'String', swig: false do
60
+ map_out code: ''
61
+ end
62
+ spec.add_extend_code 'wxSecretValue', <<~__HEREDOC
63
+ VALUE get_data()
64
+ {
65
+ size_t sz = $self->GetSize();
66
+ const void* data = $self->GetData();
67
+ return rb_enc_str_new(static_cast<const char*>(data), sz, rb_ascii8bit_encoding());
68
+ }
69
+
70
+ VALUE get_as_string()
71
+ {
72
+ size_t sz = $self->GetSize();
73
+ const void* data = $self->GetData();
74
+ return rb_utf8_str_new(static_cast<const char*>(data), sz);
75
+ }
76
+ __HEREDOC
77
+
78
+ # customize GetDefault
79
+ spec.ignore 'wxSecretStore::GetDefault', ignore_doc: false
80
+ spec.add_extend_code 'wxSecretStore', <<~__HEREDOC
81
+ static VALUE get_default()
82
+ {
83
+ wxSecretStore* result = new wxSecretStore(wxSecretStore::GetDefault());
84
+ return SWIG_NewPointerObj(result, SWIGTYPE_p_wxSecretStore, SWIG_POINTER_OWN);
85
+ }
86
+ __HEREDOC
87
+ spec.map 'wxString *errmsg' => 'String' do
88
+ map_in ignore: true, temp: 'wxString tmp', code: '$1 = &tmp;'
89
+ map_argout code: <<~__CODE
90
+ if ($result == Qfalse)
91
+ {
92
+ $result = SWIG_Ruby_AppendOutput($result, WXSTR_TO_RSTR(tmp$argnum));
93
+ }
94
+ __CODE
95
+ end
96
+ spec.map 'wxString& username' => 'String' do
97
+ map_in ignore: true, temp: 'wxString tmp', code: '$1 = &tmp;'
98
+ map_argout code: <<~__CODE
99
+ if ($result == Qtrue)
100
+ {
101
+ $result = SWIG_Ruby_AppendOutput($result, WXSTR_TO_RSTR(tmp$argnum));
102
+ }
103
+ __CODE
104
+ end
105
+ # the type matching of the username argument is tricky here since there only is the const difference
106
+ # have to explicitly overrule here for Save() incl. explicitly negating the argout mapping
107
+ spec.map 'const wxString& username' => 'String' do
108
+ map_in temp: 'wxString tmp', code: 'tmp = RSTR_TO_WXSTR($input); $1 = &tmp;'
109
+ map_argout by_ref: true
110
+ end
111
+ end
112
+
113
+ end # class SecretStore
114
+
115
+ end # class Director
116
+
117
+ end # module WXRuby3
@@ -55,9 +55,9 @@ module WXRuby3
55
55
  static const rb_data_type_t __wxTreeItemId_type = {
56
56
  "TreeItemId",
57
57
  #if RUBY_API_VERSION_MAJOR >= 3
58
- { NULL, NULL, __wxTreeItemId_size, 0, 0},
58
+ { NULL, NULL, __wxTreeItemId_size, 0, {}},
59
59
  #else
60
- { NULL, NULL, __wxTreeItemId_size, 0},
60
+ { NULL, NULL, __wxTreeItemId_size, {}},
61
61
  #endif
62
62
  NULL, NULL, RUBY_TYPED_FREE_IMMEDIATELY
63
63
  };
@@ -0,0 +1,55 @@
1
+ ---
2
+ :wxSecretStore:
3
+ :detail:
4
+ :pre:
5
+ :programlisting:
6
+ - :pattern: !ruby/regexp /\!store\..*Save.*username.*password\)/
7
+ :replace: |
8
+
9
+ ```ruby
10
+ store = Wx::SecretStore.get_default
11
+ rc, err = store.ok?
12
+ if rc
13
+ unless store.save('MyApp/MyService', username, password)
14
+ Wx.log_warning('Failed to save credentials to the system secret store.')
15
+ end
16
+ else
17
+ Wx.log_warning("This system doesn't support storing passwords securely (#{err}).")
18
+ end
19
+ ```
20
+ - :pattern: !ruby/regexp /store\..*Load.*username.*password\)/
21
+ :replace: |
22
+
23
+ ```ruby
24
+ store = Wx::SecretStore.get_default
25
+ rc, _ = store.ok?
26
+ if rc
27
+ password = Wx::SecretValue.new
28
+ rc, username = store.load('MyApp/MyService', password)
29
+ if rc
30
+ # ... use the password ...
31
+ end
32
+ end
33
+ ```
34
+ :wxSecretStore.IsOk:
35
+ :brief:
36
+ :replace:
37
+ :text: |
38
+ Check if this object can actually be used.
39
+ Returns true if the object can be used.
40
+ Returns false and an error message describing the reason if not.
41
+
42
+ :wxSecretStore.Load:
43
+ :detail:
44
+ :post:
45
+ - :pattern: !ruby/regexp /Otherwise\s+the\s+function.*arguments\./
46
+ :subst: |
47
+ Otherwise the function returns true and the username and updates the provided password argument.
48
+
49
+ :wxSecretValue:
50
+ :detail:
51
+ :post:
52
+ - :pattern: !ruby/regexp /\s+\Z/
53
+ :subst: |
54
+
55
+ @note Due to a bug using binary secrets will not work for WXGTK wxWidgets<=3.2.4 (WXOSX and WXMSW work fine). This has been fixed for later versions.
@@ -26,22 +26,30 @@ module WXRuby3
26
26
  WX_GLOBAL_CONSTANTS=false
27
27
  require 'wx'
28
28
  def handle_module(mod, table)
29
+ Wx.delayed_constants_for(mod).each do |key, delayed_const|
30
+ table[key.sym.to_s] = { type: true, value: delayed_const.to_s }
31
+ end
29
32
  mod.constants.each do |c|
30
33
  a_const = mod.const_get(c)
31
34
  if (::Module === a_const || ::Class === a_const) && a_const.name.start_with?('Wx::') # Wx:: Package submodule or Class (possibly Enum)
32
35
  handle_module(a_const, table[c.to_s] = {})
33
36
  elsif Wx::Enum === a_const
34
- table[c.to_s] = { type: a_const.class.name.split('::').last, value: "\#{a_const.class}.new(\#{a_const.to_i})" }
35
- elsif !(::Hash === a_const || ::Array === a_const)
36
- table[c.to_s] = { type: a_const.class.name.split('::').last, value: a_const } unless c == :THE_APP
37
+ table[c.to_s] = { type: true, value: "\#{a_const.class}.new(\#{a_const.to_i})" }
38
+ elsif !(::Hash === a_const || ::Array === a_const)
39
+ case a_const
40
+ when Wx::Size
41
+ table[c.to_s] = { type: true, value: "Wx::Size.new(\#{a_const.width}, \#{a_const.height})" }
42
+ when Wx::Point
43
+ table[c.to_s] = { type: true, value: "Wx::Point.new(\#{a_const.x}, \#{a_const.y})" }
44
+ else
45
+ table[c.to_s] = { type: true, value: a_const } unless c == :THE_APP
46
+ end
37
47
  end
38
48
  end
39
49
  end
40
- Wx::App.run do
41
- table = { 'Wx' => {}}
42
- handle_module(Wx, table['Wx'])
43
- STDOUT.puts JSON.dump(table)
44
- end
50
+ table = { 'Wx' => {}}
51
+ handle_module(Wx, table['Wx'])
52
+ STDOUT.puts JSON.dump(table)
45
53
  __SCRIPT
46
54
  STDERR.puts "* executing constants collection script:\n#{script}" if Director.trace?
47
55
  begin
@@ -693,15 +701,22 @@ module WXRuby3
693
701
  # at least 2 newlines to make Yard skip/forget the header comment
694
702
  fdoc.puts
695
703
  fdoc.puts
696
- fdoc.puts "module #{package.fullname}"
697
- fdoc.puts
698
- fdoc.indent do
704
+ mod_indent = 0
705
+ package.all_modules.each do |modnm|
706
+ fdoc.iputs("module #{package.fullname}", mod_indent)
707
+ fdoc.puts
708
+ mod_indent += 1
709
+ end
710
+ fdoc.indent(mod_indent) do
699
711
  gen_constants_doc(fdoc)
700
712
  gen_functions_doc(fdoc) unless no_gen?(:functions)
701
713
  gen_class_doc(fdoc) unless no_gen?(:classes)
702
714
  end
703
- fdoc.puts
704
- fdoc.puts 'end'
715
+ package.all_modules.each do |_|
716
+ mod_indent -= 1
717
+ fdoc.puts
718
+ fdoc.iputs('end', mod_indent)
719
+ end
705
720
  end
706
721
  end
707
722
 
@@ -742,7 +757,7 @@ module WXRuby3
742
757
  end
743
758
 
744
759
  def gen_constant_value(val)
745
- if ::String === val && /\A(#<(.*)>|[\w:]+\.new\(.*\))\Z/ =~ val
760
+ if ::String === val && /\A(#<(.*)>|[\w:]+\.\w+\(.*\))\Z/ =~ val
746
761
  if $2
747
762
  valstr = $2
748
763
  if /\Awx/ =~ valstr
@@ -603,7 +603,8 @@ module WXRuby3
603
603
  elsif item.value =~ /wx(Colour|Font)(\(.*\))/
604
604
  frbext = init_rb_ext_file unless frbext
605
605
  frbext.indent do
606
- frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}) { Wx::#{$1}.new#{$2} }"
606
+ code = "Wx::#{$1}.new#{$2}"
607
+ frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}, '#{code}') { #{code} }"
607
608
  end
608
609
  frbext.puts
609
610
  elsif item.value =~ /wxSystemSettings::(\w+)\((.*)\)/
@@ -611,7 +612,8 @@ module WXRuby3
611
612
  setting_mtd = $1
612
613
  args = $2.split(',').collect {|a| rb_constant_value(a) }.join(', ')
613
614
  frbext.indent do
614
- frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}) { Wx::SystemSettings.#{rb_method_name(setting_mtd)}(#{args}) }"
615
+ code = "Wx::SystemSettings.#{rb_method_name(setting_mtd)}(#{args})"
616
+ frbext.puts "Wx.add_delayed_constant(self, :#{rb_constant_name(item.name)}, '#{code}') { #{code} }"
615
617
  end
616
618
  frbext.puts
617
619
  else
@@ -233,6 +233,7 @@ module WXRuby3
233
233
  Director.Spec(pkg, 'wxPersistenceManager', requirements: %w[USE_CONFIG])
234
234
  Director.Spec(pkg, 'wxPersistentObject', requirements: %w[USE_CONFIG])
235
235
  Director.Spec(pkg, 'wxPersistentWindow', requirements: %w[USE_CONFIG])
236
+ Director.Spec(pkg, 'wxSecretStore', requirements: %w[USE_SECRETSTORE])
236
237
  }
237
238
 
238
239
  Director.Package('Wx::PRT', 'USE_PRINTING_ARCHITECTURE') do |pkg|
@@ -43,24 +43,23 @@ module WXRuby3
43
43
  @swig_version
44
44
  end
45
45
 
46
-
47
46
  def check_swig
48
47
  begin
49
48
  @swig_version = `#{WXRuby3::Config.get_config('swig')} -version`[/\d+\.\d+\.\d+/]
50
49
  rescue Exception
51
- STDERR.puts "ERROR: Could not run SWIG (#{WXRuby3::Config.get_config('swig')})"
50
+ $stderr.puts "ERROR: Could not run SWIG (#{WXRuby3::Config.get_config('swig')})"
52
51
  exit(1)
53
52
  end
54
53
 
55
- # Very old versions put --version on STDERR, not STDOUT
54
+ # Very old versions put --version on $stderr, not $stdout
56
55
  unless @swig_version
57
- STDERR.puts "Could not get version info from SWIG; " +
56
+ $stderr.puts "Could not get version info from SWIG; " +
58
57
  "is a very old version installed?.\n"
59
58
  exit(1)
60
59
  end
61
60
 
62
61
  if @swig_version < SWIG_MINIMUM_VERSION
63
- STDERR.puts "SWIG version #{@swig_version} is installed, " +
62
+ $stderr.puts "SWIG version #{@swig_version} is installed, " +
64
63
  "minimum version required is #{SWIG_MINIMUM_VERSION}.\n"
65
64
  exit(1)
66
65
  end
@@ -72,11 +71,12 @@ module WXRuby3
72
71
  check_swig unless swig_state
73
72
  inc_paths = "-I#{config.wxruby_dir} -I#{config.swig_dir}/custom"
74
73
  inc_paths << " -I#{config.swig_dir}/custom/swig#{swig_major}"
75
- sh "#{config.get_config('swig')} #{config.wx_cppflags.join(' ')} " +
76
- "#{config.extra_cppflags.join(' ')} #{config.verbose_flag} #{inc_paths} " +
77
- #"-w401 -w801 -w515 -c++ -ruby " +
78
- "-w801 -c++ -ruby " +
79
- "-o #{target} #{source}"
74
+ WXRuby3.config.sh "#{config.get_config('swig')} #{config.wx_cppflags.join(' ')} " +
75
+ "#{config.extra_cppflags.join(' ')} #{config.verbose_flag} #{inc_paths} " +
76
+ #"-w401 -w801 -w515 -c++ -ruby " +
77
+ "-w801 -c++ -ruby " +
78
+ "-o #{target} #{source}",
79
+ fail_on_error: true
80
80
  end
81
81
 
82
82
  end
@@ -205,7 +205,7 @@ module WXRuby3
205
205
  end
206
206
 
207
207
  def self.run(pid, director, target)
208
- puts "Processor.#{pid}: #{target}"
208
+ Config.instance.log_progress("Processor.#{pid}: #{target}")
209
209
  const_get(camelize(pid.to_s)).new(director, target).run
210
210
  end
211
211
 
@@ -262,6 +262,16 @@ module WXRuby3
262
262
 
263
263
  end
264
264
 
265
+ # output typemaps for common value objects like wxPoint, wxSize, wxRect and wxRealPoint,
266
+ # making sure to ALWAYS create managed copies
267
+ %w[Point Size Rect RealPoint].each do |klass|
268
+ map "const wx#{klass}&", "const wx#{klass}*", as: "Wx::#{klass}" do
269
+ map_out code: <<~__CODE
270
+ $result = SWIG_NewPointerObj((new wx#{klass}(*static_cast< const wx#{klass}* >($1))), SWIGTYPE_p_wx#{klass}, SWIG_POINTER_OWN);
271
+ __CODE
272
+ end
273
+ end
274
+
265
275
  # Integer <> wxItemKind type mappings
266
276
 
267
277
  map 'wxItemKind' => 'Integer' do
data/rakelib/prepost.rake CHANGED
@@ -23,16 +23,28 @@ namespace 'wxruby' do
23
23
 
24
24
  namespace 'post' do
25
25
 
26
- task :srcgem => %w[gem:wxwin gem:install wxruby:doc] do
26
+ task :srcgem => %w[gem:wxwin gem:install] do
27
+ $stdout.print "Generating wxRuby3 reference documentation..." if WXRuby3.config.run_silent?
28
+ Rake::Task['wxruby:doc'].invoke
29
+ $stdout.puts 'done!' if WXRuby3.config.run_silent?
27
30
  # cleanup
28
- rm_rf('rakelib')
29
- rm_rf('ext/wxruby3')
30
- rm_rf('ext/wxWidgets') if File.exist?('ext/wxWidgets')
31
+ rm_rf('rakelib', verbose: !WXRuby3.config.run_silent?)
32
+ rm_f('Rakefile', verbose: !WXRuby3.config.run_silent?)
33
+ rm_f('ext/mkrf_conf_ext.rb', verbose: !WXRuby3.config.run_silent?)
34
+ rm_rf('ext/wxruby3', verbose: !WXRuby3.config.run_silent?)
35
+ WXRuby3.config.cleanup_bootstrap
36
+ File.open(File.join(WXRuby3::Config.wxruby_root, 'ext', 'wxruby.setup.done'), 'w') { |f| f << '1' }
31
37
  end
32
38
 
33
- task :bingem => 'gem:install' do
39
+ task :binpkg => 'gem:install' do
34
40
  # cleanup
35
41
  rm_rf('rakelib')
42
+ rm_f('Rakefile')
43
+ rm_f('ext/mkrf_conf_ext.rb')
44
+ rm_rf('ext/wxruby3')
45
+ rm_f('*.pkg')
46
+ rm_f('*.sha')
47
+ File.open(File.join(WXRuby3::Config.wxruby_root, 'ext', 'wxruby.setup.done'), 'w') { |f| f << '1' }
36
48
  end
37
49
 
38
50
  namespace 'gem' do
@@ -77,3 +77,21 @@ div.wxrb-logo table td {
77
77
  font-weight: bold;
78
78
  font-size: 0.9em;
79
79
  }
80
+
81
+ #filecontents {
82
+ margin-right: 340px;
83
+ }
84
+
85
+ #filecontents blockquote {
86
+ border-left: .5em solid #e0e0e0;
87
+ margin: 10px;
88
+ padding-left: 10px;
89
+ }
90
+
91
+ #toc {
92
+ position: fixed;
93
+ overflow-y: scroll;
94
+ overflow-x: hidden;
95
+ top: 1em;
96
+ bottom: 0;
97
+ }
@@ -1,19 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  def init
4
- # It seems YARD messes things up so that a number of classes are not properly
4
+ # It seems YARD messes things up so that a lot of classes, modules and constants are not properly
5
5
  # registered in their enclosing namespaces.
6
6
  # This hack makes sure that if that is the case we fix that here.
7
- all_classes = Registry.all(:class)
8
- all_classes.each do |c|
7
+ all_objects = Registry.all(:class, :constant, :module)
8
+ all_objects.each do |c|
9
9
  if (ns = c.namespace)
10
10
  unless ns.children.any? { |nsc| nsc.path == c.path }
11
- ns.children << c # class missing from child list of enclosing namespace -> add here
11
+ ns.children << c # class/module/constant missing from child list of enclosing namespace -> add here
12
12
  end
13
13
  end
14
14
  if (ns = Registry[c.namespace.path])
15
15
  unless ns.children.any? { |nsc| nsc.path == c.path }
16
- ns.children << c # class missing from child list of enclosing namespace -> add here
16
+ ns.children << c # class/module/constant missing from child list of enclosing namespace -> add here
17
17
  end
18
18
  end
19
19
  end
@@ -31,12 +31,18 @@ module YARD # rubocop:disable Style/Documentation
31
31
  if fnames.include?(href.path)
32
32
  link.replace "{file:#{href} #{link.inner_html}}"
33
33
  elsif href.path.end_with?('_md.html') && (fname = fnames.find {|fnm| fnm.end_with?(href.path.sub(/_md.html\Z/, '.md')) })
34
- link.replace "{file:#{fname} #{link.inner_html}}"
34
+ link.replace "{file:#{fname}#{href.fragment ? "##{fragment_to_yard(href.fragment)}" : ''} #{link.inner_html}}"
35
35
  end
36
36
  end
37
37
  end
38
38
  super(html.to_s)
39
39
  end
40
+
41
+ # this does not work with mixed case labels but is good enough for us
42
+ def fragment_to_yard(s)
43
+ s.start_with?('label-') ? s : "label-#{s.gsub('-', '+').capitalize}"
44
+ end
45
+
40
46
  end
41
47
 
42
48
  Templates::Template.extra_includes << RelativeMarkdownLinks
@@ -6,6 +6,8 @@
6
6
  # wxRuby3 sampler application
7
7
  ###
8
8
 
9
+ require 'set'
10
+
9
11
  module WxRuby
10
12
 
11
13
  ART_FOLDER = File.join(__dir__, '..', 'art')
@@ -67,7 +67,7 @@ module Test
67
67
  class TestCase
68
68
 
69
69
  def self.is_ci_build?
70
- !!ENV['GITHUB_ACTION']
70
+ (ENV['GITHUB_ACTION'] || ENV['CI'])
71
71
  end
72
72
 
73
73
  def is_ci_build?
data/tests/test_config.rb CHANGED
@@ -203,13 +203,16 @@ class TestConfig < Test::Unit::TestCase
203
203
  def run_env_var_tests(cfg)
204
204
  # by default expansion is on
205
205
 
206
+ # Cirrus CI Linux builds run in privileged container without proper user env
207
+ has_user = Wx::PLATFORM == 'WXMSW' || ENV['USER']
208
+
206
209
  # add a number of entries for env var in new group 'Environment'
207
210
  cfg['/Environment/HOME'] = '$HOME'
208
- cfg['Environment'].USER = Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}'
211
+ cfg['Environment'].USER = Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}' if has_user
209
212
  cfg['/Environment/PATH'] = '$(PATH)'
210
213
 
211
214
  assert_equal(ENV['HOME'], cfg.Environment['HOME'])
212
- assert_equal(ENV[Wx::PLATFORM == 'WXMSW' ? 'USERNAME' : 'USER'], cfg['/Environment/USER'])
215
+ assert_equal(ENV[Wx::PLATFORM == 'WXMSW' ? 'USERNAME' : 'USER'], cfg['/Environment/USER']) if has_user
213
216
  assert_equal(ENV['PATH'], cfg.Environment.PATH)
214
217
 
215
218
  # test escaping
@@ -225,9 +228,9 @@ class TestConfig < Test::Unit::TestCase
225
228
 
226
229
  assert_equal('${NonExistingLongNonsenseVariable}', cfg.Environment['NONSENSE'])
227
230
 
228
- cfg['/Environment/MULTIPLE'] = "$HOME / #{Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}'}"
231
+ cfg['/Environment/MULTIPLE'] = "$HOME / #{Wx::PLATFORM == 'WXMSW' ? '%USERNAME%' : '${USER}'}" if has_user
229
232
 
230
- assert_equal("#{ENV['HOME']} / #{Wx::PLATFORM == 'WXMSW' ? ENV['USERNAME'] : ENV['USER']}", cfg.Environment['MULTIPLE'])
233
+ assert_equal("#{ENV['HOME']} / #{Wx::PLATFORM == 'WXMSW' ? ENV['USERNAME'] : ENV['USER']}", cfg.Environment['MULTIPLE']) if has_user
231
234
 
232
235
  # disable env var expansion
233
236
  cfg.expand_env_vars = false