From f3cecbd54081000815ba1e3c585fb7527f2b20f3 Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Sat, 14 Jan 2023 15:49:15 +0100 Subject: [PATCH 1/4] Move the supported table out of README This changes the workflow to have a rake task to create a database.md file and then render that into the generated documentation. The release process is also enhanced to include the generated database.md file. This should allow sites like rubydoc.info correctly render it as well, though this hasn't been tested. It also introduces a GitHub Action workflow to build GitHub Pages with the generated documentation. That means that the documentation should always be up to date and no manual steps are needed anymore. It also saves a lot of noise in the git log. --- .github/workflows/pages.yml | 41 +++++++++++++++++++++++++ .github/workflows/release.yml | 2 ++ .gitignore | 3 ++ .yardopts | 2 ++ Gemfile | 2 ++ README.md | 57 ----------------------------------- Rakefile | 44 ++++++++++++++++++--------- facterdb.gemspec | 4 +-- 8 files changed, 82 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/pages.yml create mode 100644 .yardopts diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml new file mode 100644 index 00000000..8c6b0532 --- /dev/null +++ b/.github/workflows/pages.yml @@ -0,0 +1,41 @@ +name: Deploy docs to Pages + +on: + push: + branches: ['master'] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: "pages" + cancel-in-progress: true + +jobs: + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Set up Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.3' + bundler-cache: true + - name: Build docs + run: bundle exec rake yard + - name: Set up Pages + uses: actions/configure-pages@v2 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: doc + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 03b37885..e5cef1fa 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -17,6 +17,8 @@ jobs: ruby-version: '3.3' env: BUNDLE_WITHOUT: release + - name: Generate database + run: bundle exec rake database - name: Build gem run: gem build --strict --verbose *.gemspec - name: Publish gem to rubygems.org diff --git a/.gitignore b/.gitignore index b5e9fc82..e9c16ea8 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ coverage/ .envrc vendor/ .vendor/ +.yardoc packer_cache/ *.box +database.md +doc/ hugo/public diff --git a/.yardopts b/.yardopts new file mode 100644 index 00000000..0bd52e48 --- /dev/null +++ b/.yardopts @@ -0,0 +1,2 @@ +--list-undoc +--files CHANGELOG.md,database.md diff --git a/Gemfile b/Gemfile index e0be8ac4..fb218f4e 100644 --- a/Gemfile +++ b/Gemfile @@ -7,4 +7,6 @@ gem 'facter', ENV.fetch('FACTER_GEM_VERSION', nil), require: false group :development do gem 'faraday-retry', require: false gem 'github_changelog_generator', '>= 1.16.4', require: false + gem 'yard' + gem 'redcarpet' end diff --git a/README.md b/README.md index 4d0bd809..c32966d5 100644 --- a/README.md +++ b/README.md @@ -57,63 +57,6 @@ require 'facterdb' FacterDB::get_facts('osfamily=Debian') ``` -## Facter version and Operating System coverage - -| operating system | 4.0 | 4.1 | 4.2 | 4.3 | 4.4 | 4.5 | 4.6 | 4.7 | -| ------------------------ | --- | --- | --- | --- | --- | --- | --- | --- | -| AlmaLinux 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| AlmaLinux 9 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| Amazon 2 | | | | | | 1 | | | -| Amazon 2022 | | | 1 | | | | | | -| Archlinux | | | 1 | 1 | 1 | 1 | 1 | 1 | -| CentOS 7 | 1 | 1 | 1 | 1 | 1 | 1 | | | -| CentOS 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| CentOS 9 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Darwin 20 | | | 1 | | | | | | -| Debian 11 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| Debian 12 | | | 2 | 2 | 2 | 1 | 1 | 1 | -| Fedora 36 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Fedora 37 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Fedora 38 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Fedora 39 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| FreeBSD 11 | 1 | 1 | 1 | | | | | | -| FreeBSD 12 | 1 | 1 | 1 | | | 1 | | | -| FreeBSD 13 | 1 | 1 | 1 | 1 | 1 | 1 | | | -| Gentoo | | | 1 | 1 | 2 | 1 | 1 | 1 | -| OpenBSD 7.5 | | | | | | | | 1 | -| OracleLinux 7 | 1 | | 1 | | | | | | -| OracleLinux 8 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| OracleLinux 9 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Pop!_OS 21.10 | | | 1 | | | | | | -| RedHat 7 | 1 | | 1 | | | | | | -| RedHat 8 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| RedHat 9 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Rocky 8 | 1 | 1 | 1 | 1 | 1 | 1 | | | -| Rocky 9 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| SLES 12 | | | 1 | 1 | 1 | | | | -| SLES 15 | | | 1 | | | | | | -| Scientific 7 | 1 | | 1 | | | | | | -| Solaris 11 | 1 | | | | | | | | -| Ubuntu 18.04 | 1 | 1 | 1 | 1 | 1 | 1 | | | -| Ubuntu 20.04 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | -| Ubuntu 21.04 | 1 | 1 | 1 | | | | | | -| Ubuntu 21.10 | 1 | 1 | 1 | | | | | | -| Ubuntu 22.04 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Ubuntu 22.10 | | | 1 | | | | | | -| Windows 10 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Windows 11 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Windows Server 2012 | | | 1 | 1 | 1 | | | | -| Windows Server 2012 R2 | | | 1 | 1 | 1 | | | | -| Windows Server 2016 | | | 1 | 1 | 1 | | | | -| Windows Server 2016 Core | | | 1 | 1 | 1 | | | | -| Windows Server 2019 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Windows Server 2019 Core | | | 1 | 1 | 1 | | | | -| Windows Server 2022 | | | 1 | 1 | 1 | 1 | 1 | 1 | -| Windows Server 2022 Core | | | 1 | 1 | 1 | | | | -| openSUSE 15 | 1 | 1 | 1 | 1 | 1 | 1 | | 1 | - -Where the number (1, 2 etc.) are the number of factsets for that OS and facter combination (e.g., x86_64 and i386 architectures). - ## Add new Operating System support There is `Vagrantfile` to automagically populate `facts` for all supported operating systems by spawning a new VM and launches a provisioning scripts. diff --git a/Rakefile b/Rakefile index a7b1acef..ea921163 100644 --- a/Rakefile +++ b/Rakefile @@ -24,6 +24,15 @@ rescue LoadError end end +begin + require 'yard' +rescue LoadError + # No yard +else + YARD::Rake::YardocTask.new + task :yard => :database +end + # Generate a human-friendly OS label based on a given factset def factset_to_os_label(fs) os_rel = '???' @@ -99,8 +108,8 @@ def factset_to_os_label(fs) label end -desc 'generate a markdown table of Facter/OS coverage (for the README)' -task :table do +desc 'generate a markdown table of Facter/OS coverage' +task :database do require_relative 'lib/facterdb' # Turn on the source injection old_env = ENV.fetch('FACTERDB_INJECT_SOURCE', nil) @@ -130,24 +139,31 @@ task :table do string_pieces.zip(number_pieces).flatten.compact end - readme_path = File.expand_path(File.join(__dir__, 'README.md')) - readme = File.read(readme_path).split("\n") - new_readme = readme[0..readme.index { |r| r.start_with?('| ') } - 1] # Write out a nice table - os_version_width = (os_versions.map { |x| x.size } + [17]).max - new_readme << "| #{'operating system'.center(os_version_width)} |#{facter_versions.map { |x| " #{x} |" }.join}" - new_readme << "| #{'-' * os_version_width} |#{facter_versions.map { |_x| ' --- |' }.join}" + os_version_width = (os_versions.map{|x| x.size } + [17]).max + facter_width = 3 + + rows = [ + ['operating system'.center(os_version_width)] + facter_versions, + ['-' * os_version_width] + ['-' * facter_width] * facter_versions.length, + ] + os_versions.each do |label| - fvs = facter_versions.map { |facter_version| os_facter_matrix[label][facter_version] || 0 } - row = "| #{label.ljust(os_version_width)} |" - fvs.each { |fv| row += ((fv > 0) ? " #{fv.to_s.center(3)} |" : ' |') } - new_readme << row + fvs = facter_versions.map do |facter_version| + version = os_facter_matrix[label][facter_version] || 0 + version > 0 ? version.to_s : '' + end + rows << [label.ljust(os_version_width)] + fvs.map { |fv| fv.center(facter_width) } end - File.open(readme_path, 'w') do |fd| - fd.puts (new_readme + readme[readme.rindex { |r| r.start_with?('| ') } + 1..-1]).join("\n") + content = "# Facter version and Operating System coverage\n\n" + rows.each do |row| + content += "| #{row.join(' | ')} |\n" end + content += "\n\nWhere the number (1, 2 etc.) are the number of factsets for that OS and facter combination (e.g., x86_64 and i386 architectures).\n" + + File.write(File.join(__dir__, 'database.md'), content) end begin diff --git a/facterdb.gemspec b/facterdb.gemspec index 4704689d..5dfb7458 100644 --- a/facterdb.gemspec +++ b/facterdb.gemspec @@ -11,8 +11,8 @@ Gem::Specification.new do |s| s.description = 'Contains facts from many Facter version on many Operating Systems' s.licenses = 'Apache-2.0' - s.files = `git ls-files`.split("\n") - s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } + s.files = `git ls-files`.split("\n") + ['database.md'] + s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } # we have that configured in our CI file s.required_ruby_version = Gem::Requirement.new('>= 2.7.0') From d2d29bdc7749a3ba921abe068fdb69289f3d7405 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Tue, 14 May 2024 18:01:32 -0400 Subject: [PATCH 2/4] Create lists of facts Based on #262 --- .gitignore | 2 +- .yardopts | 4 +-- Gemfile | 2 +- Rakefile | 90 +++++++++++++++++++++++++++++++++++++++++++----- facterdb.gemspec | 4 +-- facts/README.md | 6 ++-- 6 files changed, 92 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index e9c16ea8..b9995038 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,6 @@ vendor/ .yardoc packer_cache/ *.box -database.md doc/ +database/ hugo/public diff --git a/.yardopts b/.yardopts index 0bd52e48..3a908c59 100644 --- a/.yardopts +++ b/.yardopts @@ -1,2 +1,2 @@ ---list-undoc ---files CHANGELOG.md,database.md +--title 'FacterDB Documentation' +--files CHANGELOG.md,database/* diff --git a/Gemfile b/Gemfile index fb218f4e..f1aa3117 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,6 @@ gem 'facter', ENV.fetch('FACTER_GEM_VERSION', nil), require: false group :development do gem 'faraday-retry', require: false gem 'github_changelog_generator', '>= 1.16.4', require: false - gem 'yard' gem 'redcarpet' + gem 'yard' end diff --git a/Rakefile b/Rakefile index ea921163..33feff58 100644 --- a/Rakefile +++ b/Rakefile @@ -30,7 +30,7 @@ rescue LoadError # No yard else YARD::Rake::YardocTask.new - task :yard => :database + task yard: :database # rubocop:disable Rake/Desc end # Generate a human-friendly OS label based on a given factset @@ -108,9 +108,36 @@ def factset_to_os_label(fs) label end +def factset_hash_to_markdown(h, caption1: nil, caption2: nil, caption3: nil) + content = '' + + h.each do |label1, data1| + indent = '' + content += "#{indent} - " + content += "#{caption1} " if caption1 + content += "#{label1}\n" + indent += ' ' + data1.each do |label2, data2| + content += "#{indent}- " + content += "#{caption2} " if caption2 + content += "#{label2}:" + + data2.each do |label3| + content += " #{caption3}" if caption3 + content += " #{label3}" + end + content += "\n" + end + end + + content +end + desc 'generate a markdown table of Facter/OS coverage' task :database do require_relative 'lib/facterdb' + FileUtils.mkdir_p 'database' + # Turn on the source injection old_env = ENV.fetch('FACTERDB_INJECT_SOURCE', nil) ENV['FACTERDB_INJECT_SOURCE'] = 'true' @@ -121,15 +148,42 @@ task :database do facter_versions = factsets.map do |x| Gem::Version.new(x[:facterversion].split('.')[0..1].join('.')) end.uniq.sort.map(&:to_s) + + # Old table os_facter_matrix = {} + # New lists + os_facter_arch_list = {} + os_arch_facter_list = {} + facter_os_arch_list = {} + # Can't think of any reason facter_arch_os_list would be useful + arch_os_facter_list = {} + # Can't think of any reason arch_facter_os_list would be useful + # Process the facts and create a hash of all the OS and facter combinations factsets.each do |facts| fv = facts[:facterversion].split('.')[0..1].join('.') + arch = facts[:hardwaremodel] || 'Missing' label = factset_to_os_label(facts) os_facter_matrix[label] ||= {} os_facter_matrix[label][fv] ||= 0 os_facter_matrix[label][fv] += 1 + + os_facter_arch_list[label] ||= {} + os_facter_arch_list[label][fv] ||= [] + os_facter_arch_list[label][fv] << arch + + os_arch_facter_list[label] ||= {} + os_arch_facter_list[label][arch] ||= [] + os_arch_facter_list[label][arch] << fv + + facter_os_arch_list[fv] ||= {} + facter_os_arch_list[fv][label] ||= [] + facter_os_arch_list[fv][label] << arch + + arch_os_facter_list[arch] ||= {} + arch_os_facter_list[arch][label] ||= [] + arch_os_facter_list[arch][label] << fv end # Extract the OS list os_versions = os_facter_matrix.keys.uniq.sort_by do |label| @@ -139,31 +193,51 @@ task :database do string_pieces.zip(number_pieces).flatten.compact end - # Write out a nice table - os_version_width = (os_versions.map{|x| x.size } + [17]).max + os_version_width = (os_versions.map { |x| x.size } + [17]).max facter_width = 3 rows = [ ['operating system'.center(os_version_width)] + facter_versions, - ['-' * os_version_width] + ['-' * facter_width] * facter_versions.length, + ['-' * os_version_width] + (['-' * facter_width] * facter_versions.length), ] os_versions.each do |label| fvs = facter_versions.map do |facter_version| version = os_facter_matrix[label][facter_version] || 0 - version > 0 ? version.to_s : '' + (version > 0) ? version.to_s : '' end - rows << [label.ljust(os_version_width)] + fvs.map { |fv| fv.center(facter_width) } + rows << ([label.ljust(os_version_width)] + fvs.map { |fv| fv.center(facter_width) }) end - content = "# Facter version and Operating System coverage\n\n" + content = "# @title Table of Available Factsets\n\n" + content += "# Facter version and Operating System coverage\n\n" rows.each do |row| content += "| #{row.join(' | ')} |\n" end content += "\n\nWhere the number (1, 2 etc.) are the number of factsets for that OS and facter combination (e.g., x86_64 and i386 architectures).\n" - File.write(File.join(__dir__, 'database.md'), content) + File.write(File.join(__dir__, 'database', 'table.md'), content) + + content = "# @title Available Factsets Grouped By OS -> Facter -> Architecture\n\n" + content += "# Available Facts Grouped By OS -> Facter\n\n" + content += factset_hash_to_markdown(os_facter_arch_list, caption2: 'Facter') + File.write(File.join(__dir__, 'database', 'list_os_facter_arch.md'), content) + + content = "# @title Available Factsets Grouped By OS -> Architecture -> Facter Version\n\n" + content += "# Available Facts Grouped By OS -> Arch\n\n" + content += factset_hash_to_markdown(os_arch_facter_list) + File.write(File.join(__dir__, 'database', 'list_os_arch_facter.md'), content) + + content = "# @title Available Factsets Grouped By Facter Version -> OS -> Architecture\n\n" + content += "# Available Facts Grouped By Facter -> OS\n\n" + content += factset_hash_to_markdown(facter_os_arch_list, caption1: 'Facter') + File.write(File.join(__dir__, 'database', 'list_facter_os_arch.md'), content) + + content = "# @title Available Factsets Grouped By Architecture -> OS -> Facter Version\n\n" + content += "# Available Facts Grouped By Arch -> OS\n\n" + content += factset_hash_to_markdown(arch_os_facter_list) + File.write(File.join(__dir__, 'database', 'list_arch_os_facter.md'), content) end begin diff --git a/facterdb.gemspec b/facterdb.gemspec index 5dfb7458..a5e56f2d 100644 --- a/facterdb.gemspec +++ b/facterdb.gemspec @@ -11,8 +11,8 @@ Gem::Specification.new do |s| s.description = 'Contains facts from many Facter version on many Operating Systems' s.licenses = 'Apache-2.0' - s.files = `git ls-files`.split("\n") + ['database.md'] - s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } + s.files = `git ls-files`.split("\n") + Dir['database/*'] + s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) } # we have that configured in our CI file s.required_ruby_version = Gem::Requirement.new('>= 2.7.0') diff --git a/facts/README.md b/facts/README.md index b1971cd6..21bb5aa7 100644 --- a/facts/README.md +++ b/facts/README.md @@ -45,12 +45,14 @@ Windows systems are also available. $ vagrant up --provision windows-server-2019-x86_64 windows-server-2022-x86_64 windows-10-x86_64 windows-11-x86_64 ``` -Once new facts are built, the table listing supported facter versions and operating systems needs to be updated. +You can build a list of supported facter versions and operating systems: ``` -$ bundle exec rake table +$ bundle exec rake database ``` +These are also included in our YARD documentation build. + ### Converted Facts Not all facts can (or should) be built from VMs. From aea3ffabe58bd48b76977690466f4549fb68b338 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Thu, 16 May 2024 15:20:06 -0400 Subject: [PATCH 3/4] Normalize archs --- Rakefile | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Rakefile b/Rakefile index 33feff58..765fbd66 100644 --- a/Rakefile +++ b/Rakefile @@ -108,6 +108,17 @@ def factset_to_os_label(fs) label end +def normalize_arch(arch_str) + case arch_str + when 'x86_64', 'amd64' + 'x86_64' + when 'i386' + 'i386' + else + arch_str + end +end + def factset_hash_to_markdown(h, caption1: nil, caption2: nil, caption3: nil) content = '' @@ -163,7 +174,7 @@ task :database do # Process the facts and create a hash of all the OS and facter combinations factsets.each do |facts| fv = facts[:facterversion].split('.')[0..1].join('.') - arch = facts[:hardwaremodel] || 'Missing' + arch = normalize_arch(facts[:hardwaremodel]) || 'Missing Value' label = factset_to_os_label(facts) os_facter_matrix[label] ||= {} os_facter_matrix[label][fv] ||= 0 From 57c1056cc12dc721a73460e552bfd11dfef86e30 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Sat, 18 May 2024 22:44:52 -0400 Subject: [PATCH 4/4] Github Actions updates --- .github/workflows/pages.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml index 8c6b0532..8c2f2310 100644 --- a/.github/workflows/pages.yml +++ b/.github/workflows/pages.yml @@ -31,11 +31,11 @@ jobs: - name: Build docs run: bundle exec rake yard - name: Set up Pages - uses: actions/configure-pages@v2 + uses: actions/configure-pages@v5 - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v3 with: path: doc - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v1 + uses: actions/deploy-pages@v4