├── .github
└── workflows
│ ├── image.yml
│ └── main.yml
├── .gitignore
├── .idea
└── .gitignore
├── .rubocop.yml
├── CHANGELOG.md
├── Dockerfile
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── bin
├── console
└── setup
├── containers.conf
├── exe
└── pgpm
├── lib
├── pgpm.rb
└── pgpm
│ ├── arch.rb
│ ├── aspects
│ └── inheritance_tracker.rb
│ ├── cache.rb
│ ├── commands.rb
│ ├── contrib
│ ├── amcheck.rb
│ ├── auth_delay.rb
│ ├── auto_explain.rb
│ ├── basebackup_to_shell.rb
│ ├── btree_gist.rb
│ ├── dblink.rb
│ ├── pgcrypto.rb
│ ├── plpython3u.rb
│ └── postgres_fdw.rb
│ ├── deb
│ ├── Dockerfile
│ ├── builder.rb
│ ├── pbuilder_install_script.sh
│ ├── scripts
│ │ ├── install_default_control.sh
│ │ ├── pg_config.sh
│ │ └── prepare_artifacts.sh
│ ├── spec.rb
│ └── templates
│ │ ├── changelog.erb
│ │ ├── control.erb
│ │ ├── copyright.erb
│ │ ├── files.erb
│ │ └── rules.erb
│ ├── on_demand_file.rb
│ ├── os.rb
│ ├── os
│ ├── darwin.rb
│ ├── debian.rb
│ ├── linux.rb
│ ├── red_hat.rb
│ └── unix.rb
│ ├── package.rb
│ ├── package
│ ├── abstract_package.rb
│ ├── building.rb
│ ├── contrib.rb
│ ├── dependencies.rb
│ ├── enumerating.rb
│ ├── git.rb
│ ├── git_hub.rb
│ ├── initialization.rb
│ ├── make.rb
│ ├── metadata.rb
│ ├── naming.rb
│ ├── native.rb
│ ├── packaging.rb
│ ├── pgxn.rb
│ ├── rust.rb
│ ├── source.rb
│ ├── subscripting.rb
│ ├── version.rb
│ ├── versioning.rb
│ └── with_path.rb
│ ├── podman.rb
│ ├── postgres
│ ├── distribution.rb
│ └── redhat_based_pgdg.rb
│ ├── rpm.rb
│ ├── rpm
│ ├── builder.rb
│ ├── mock
│ │ ├── config.rb
│ │ ├── configs
│ │ │ ├── rocky+epel-9-aarch64+pgdg.cfg
│ │ │ └── rocky+epel-9-x86_64+pgdg.cfg
│ │ └── operation.rb
│ ├── scripts
│ │ ├── pg_config.sh
│ │ └── prepare_artifacts.sh
│ └── spec.rb
│ ├── scoped_object.rb
│ └── version.rb
├── packages
├── acl.rb
├── age.rb
├── aggs_for_arrays.rb
├── aggs_for_vecs.rb
├── anon.rb
├── arraymath.rb
├── asn1oid.rb
├── aws_s3.rb
├── base36.rb
├── base62.rb
├── bgw_replstatus.rb
├── chkpass.rb
├── citus.rb
├── citus_columnar.rb
├── columnar.rb
├── count_distinct.rb
├── country.rb
├── credcheck.rb
├── cryptint.rb
├── currency.rb
├── data_historization.rb
├── db2_fdw.rb
├── dbt2.rb
├── ddl_historization.rb
├── ddlx.rb
├── ddsketch.rb
├── debversion.rb
├── decoder_raw.rb
├── decoderbufs.rb
├── duckdb_fdw.rb
├── emaj.rb
├── envvar.rb
├── explain_ui.rb
├── extra_window_functions.rb
├── faker.rb
├── financial.rb
├── firebird_fdw.rb
├── first_last_agg.rb
├── floatfile.rb
├── floatvec.rb
├── geoip.rb
├── gzip.rb
├── h3.rb
├── h3_postgis.rb
├── hdfs_fdw.rb
├── hll.rb
├── hstore_pllua.rb
├── hstore_plluau.rb
├── http.rb
├── hunspell_cs_cz.rb
├── hunspell_de_de.rb
├── hunspell_en_us.rb
├── hunspell_fr.rb
├── hunspell_ne_np.rb
├── hunspell_nl_nl.rb
├── hunspell_nn_no.rb
├── hunspell_pt_pt.rb
├── hunspell_ru_ru.rb
├── hunspell_ru_ru_aot.rb
├── hypopg.rb
├── icu_ext.rb
├── imgsmlr.rb
├── index_advisor.rb
├── ip4r.rb
├── jdbc_fdw.rb
├── jsquery.rb
├── kafka_fdw.rb
├── log_fdw.rb
├── logerrors.rb
├── login_hook.rb
├── lower_quantile.rb
├── md5hash.rb
├── meta.rb
├── mimeo.rb
├── mobilitydb.rb
├── mongo_fdw.rb
├── multicorn.rb
├── mysql_fdw.rb
├── noset.rb
├── numeral.rb
├── odbc_fdw.rb
├── ogr_fdw.rb
├── omnigres
│ ├── extension_discovery.rb
│ ├── omni.rb
│ ├── omni_auth.rb
│ ├── omni_aws.rb
│ ├── omni_cloudevents.rb
│ ├── omni_containers.rb
│ ├── omni_http.rb
│ ├── omni_httpc.rb
│ ├── omni_httpd.rb
│ ├── omni_id.rb
│ ├── omni_json.rb
│ ├── omni_ledger.rb
│ ├── omni_manifest.rb
│ ├── omni_mimetypes.rb
│ ├── omni_os.rb
│ ├── omni_polyfill.rb
│ ├── omni_python.rb
│ ├── omni_regex.rb
│ ├── omni_schema.rb
│ ├── omni_seq.rb
│ ├── omni_session.rb
│ ├── omni_sql.rb
│ ├── omni_txn.rb
│ ├── omni_types.rb
│ ├── omni_var.rb
│ ├── omni_vfs.rb
│ ├── omni_vfs_types_v1.rb
│ ├── omni_web.rb
│ ├── omni_xml.rb
│ ├── omni_yaml.rb
│ ├── package.rb
│ └── scripts
│ │ └── generate_upgrade.sh
├── omnisketch.rb
├── oracle_fdw.rb
├── orafce.rb
├── pagevis.rb
├── passwordcheck_cracklib.rb
├── periods.rb
├── permuteseq.rb
├── pg_analytics.rb
├── pg_auditor.rb
├── pg_auth_mon.rb
├── pg_background.rb
├── pg_base58.rb
├── pg_bestmatch.rb
├── pg_bigm.rb
├── pg_bulkload.rb
├── pg_cardano.rb
├── pg_catcheck.rb
├── pg_cheat_funcs.rb
├── pg_checksums.rb
├── pg_crash.rb
├── pg_cron.rb
├── pg_dbms_job.rb
├── pg_dbms_lock.rb
├── pg_dbms_metadata.rb
├── pg_dirtyread.rb
├── pg_drop_events.rb
├── pg_duckdb.rb
├── pg_duration.rb
├── pg_extra_time.rb
├── pg_fact_loader.rb
├── pg_failover_slots.rb
├── pg_fio.rb
├── pg_fkpart.rb
├── pg_geohash.rb
├── pg_graphql.rb
├── pg_hashids.rb
├── pg_hashlib.rb
├── pg_hint_plan.rb
├── pg_html5_email_address.rb
├── pg_idkit.rb
├── pg_incremental.rb
├── pg_ivm.rb
├── pg_jobmon.rb
├── pg_jsonschema.rb
├── pg_later.rb
├── pg_math.rb
├── pg_mooncake.rb
├── pg_net.rb
├── pg_orphaned.rb
├── pg_parquet.rb
├── pg_partman.rb
├── pg_permissions.rb
├── pg_polyline.rb
├── pg_proctab.rb
├── pg_profile.rb
├── pg_protobuf.rb
├── pg_qualstats.rb
├── pg_rational.rb
├── pg_readme.rb
├── pg_readonly.rb
├── pg_relusage.rb
├── pg_repack.rb
├── pg_rrule.rb
├── pg_savior.rb
├── pg_search.rb
├── pg_session_jwt.rb
├── pg_show_plans.rb
├── pg_similarity.rb
├── pg_smtp_client.rb
├── pg_snakeoil.rb
├── pg_sphere.rb
├── pg_sqlog.rb
├── pg_squeeze.rb
├── pg_stat_kcache.rb
├── pg_stat_monitor.rb
├── pg_statement_rollback.rb
├── pg_store_plans.rb
├── pg_strom.rb
├── pg_summarize.rb
├── pg_task.rb
├── pg_tde.rb
├── pg_text_semver.rb
├── pg_tiktoken.rb
├── pg_tle.rb
├── pg_top.rb
├── pg_track_settings.rb
├── pg_upless.rb
├── pg_uuidv7.rb
├── pg_wait_sampling.rb
├── pg_xenophile.rb
├── pgaudit.rb
├── pgauditlogtofile.rb
├── pgautofailover.rb
├── pgbouncer_fdw.rb
├── pgcozy.rb
├── pgdd.rb
├── pgemailaddr.rb
├── pgextwlist.rb
├── pgfaceting.rb
├── pgfincore.rb
├── pgjwt.rb
├── pgl_ddl_deploy.rb
├── pglite_fusion.rb
├── pglogical.rb
├── pglogical_origin.rb
├── pglogical_ticker.rb
├── pgmemcache.rb
├── pgmeminfo.rb
├── pgml.rb
├── pgmp.rb
├── pgmq.rb
├── pgnodemx.rb
├── pgpcre.rb
├── pgpdf.rb
├── pgq.rb
├── pgqr.rb
├── pgroonga.rb
├── pgroonga_database.rb
├── pgrouting.rb
├── pgsmcrypto.rb
├── pgsodium.rb
├── pgsql_tweaks.rb
├── pgtap.rb
├── pgtt.rb
├── pguecc.rb
├── pgvector.rb
├── plan_filter.rb
├── pldbgapi.rb
├── pljava.rb
├── pllua.rb
├── plluau.rb
├── plpgsql_check.rb
├── plprofiler.rb
├── plproxy.rb
├── plprql.rb
├── plr.rb
├── plsh.rb
├── plv8.rb
├── pointcloud.rb
├── pointcloud_postgis.rb
├── powa.rb
├── pre_prepare.rb
├── prefix.rb
├── prioritize.rb
├── q3c.rb
├── quantile.rb
├── random.rb
├── rdkit.rb
├── redis.rb
├── redis_fdw.rb
├── repmgr.rb
├── roaringbitmap.rb
├── rum.rb
├── safeupdate.rb
├── schedoc.rb
├── semver.rb
├── sequential_uuids.rb
├── session_variable.rb
├── set_user.rb
├── shacrypt.rb
├── smlar.rb
├── sqlite_fdw.rb
├── sslutils.rb
├── supabase_vault.rb
├── supautils.rb
├── system_stats.rb
├── table_log.rb
├── table_version.rb
├── tdigest.rb
├── tds_fdw.rb
├── temporal_tables.rb
├── timeit.rb
├── timescale
│ ├── timescaledb.rb
│ └── timescaledb_apache2.rb
├── timescaledb_toolkit.rb
├── timeseries.rb
├── timestamp9.rb
├── toastinfo.rb
├── topn.rb
├── uint.rb
├── uint128.rb
├── unit.rb
├── uri.rb
├── url_encode.rb
├── vasco.rb
├── vchord.rb
├── vectorize.rb
├── vectorscale.rb
├── wal2json.rb
├── wal2mongo.rb
├── wrappers.rb
├── xxhash.rb
├── zhparser.rb
└── zstd.rb
├── pgpm.gemspec
├── pigsty.rb
├── sig
└── pgpm.rbs
└── test
├── test_helper.rb
├── test_pgpm.rb
└── test_pgpm_package_version.rb
/.github/workflows/image.yml:
--------------------------------------------------------------------------------
1 | name: Container image
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | env:
9 | REGISTRY: ghcr.io
10 | IMAGE_NAME: ${{ github.repository }}
11 |
12 | jobs:
13 | build:
14 |
15 | strategy:
16 | matrix:
17 | platform: [ amd64, arm64 ]
18 |
19 | runs-on: ${{ fromJSON('["warp-ubuntu-2204-x64-4x", "warp-ubuntu-2204-arm64-16x"]')[matrix.platform == 'arm64'] }}
20 | name: Build container image
21 |
22 | permissions:
23 | contents: read
24 | packages: write
25 | # This is used to complete the identity challenge
26 | # with sigstore/fulcio when running outside of PRs.
27 | id-token: write
28 |
29 | steps:
30 | - uses: actions/checkout@v4
31 |
32 | - name: Set up Docker Buildx
33 | uses: docker/setup-buildx-action@v3
34 | with:
35 | driver-opts: |
36 | network=host
37 |
38 | - name: Log in to the Container registry
39 | uses: docker/login-action@v3
40 | with:
41 | registry: ${{ env.REGISTRY }}
42 | username: ${{ github.actor }}
43 | password: ${{ secrets.GITHUB_TOKEN }}
44 |
45 | - name: Extract metadata (tags, labels) for Docker
46 | id: meta
47 | uses: docker/metadata-action@v5
48 | with:
49 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
50 |
51 | - name: Build and push Docker image
52 | id: push
53 | uses: docker/build-push-action@v6
54 | with:
55 | target: pgpm
56 | platforms: linux/${{ matrix.platform }}
57 | context: .
58 | push: true
59 | tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-${{ matrix.platform }}
60 | labels: ${{ steps.meta.outputs.labels }}
61 | allow: security.insecure
62 | cache-from: type=gha,url=http://127.0.0.1:49160/
63 | cache-to: type=gha,url=http://127.0.0.1:49160/,mode=max
64 | provenance: false
65 |
66 |
67 | manifest:
68 |
69 | needs: build
70 | runs-on: ubuntu-latest
71 |
72 | permissions:
73 | contents: read
74 | packages: write
75 |
76 | steps:
77 | - uses: actions/checkout@v3
78 |
79 | - name: Log in to the Container registry
80 | uses: docker/login-action@v3
81 | with:
82 | registry: ${{ env.REGISTRY }}
83 | username: ${{ github.actor }}
84 | password: ${{ secrets.GITHUB_TOKEN }}
85 |
86 | - name: Extract metadata (tags, labels) for Docker
87 | id: meta
88 | uses: docker/metadata-action@v5
89 | with:
90 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
91 |
92 | - name: Create and push manifest images
93 | uses: Noelware/docker-manifest-action@master # or use a pinned version in the Releases tab
94 | with:
95 | inputs: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
96 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-amd64,${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-arm64
97 | push: true
98 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Ruby
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 |
8 | pull_request:
9 |
10 | jobs:
11 | build:
12 | runs-on: ubuntu-latest
13 | name: Ruby ${{ matrix.ruby }}
14 | strategy:
15 | matrix:
16 | ruby:
17 | - '3.3.5'
18 | - '3.4.1'
19 |
20 | steps:
21 | - uses: actions/checkout@v4
22 | - name: Set up Ruby
23 | uses: ruby/setup-ruby@v1
24 | with:
25 | ruby-version: ${{ matrix.ruby }}
26 | bundler-cache: true
27 | - name: Run the default task
28 | run: bundle exec rake
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.bundle/
2 | /.yardoc
3 | /_yardoc/
4 | /coverage/
5 | /doc/
6 | /pkg/
7 | /spec/reports/
8 | /tmp/
9 | .idea
10 | Gemfile.lock
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/.rubocop.yml:
--------------------------------------------------------------------------------
1 | AllCops:
2 | TargetRubyVersion: 3.3
3 |
4 | Style/StringLiterals:
5 | EnforcedStyle: double_quotes
6 |
7 | Style/StringLiteralsInInterpolation:
8 | EnforcedStyle: double_quotes
9 |
10 | Style/FormatStringToken:
11 | EnforcedStyle: template
12 |
13 | ## Settings below are meant to be enabled (at least some of them)
14 | ## but in order to make rubocop useful first for correcting obvious things,
15 | ## they were disabled for the time being. TODO: review
16 |
17 | Style/Documentation:
18 | Enabled: false
19 |
20 | Metrics/MethodLength:
21 | Enabled: false
22 |
23 | Metrics/AbcSize:
24 | Enabled: false
25 |
26 | Metrics/ClassLength:
27 | Enabled: false
28 |
29 | Metrics/PerceivedComplexity:
30 | Enabled: false
31 |
32 | Metrics/CyclomaticComplexity:
33 | Enabled: false
34 |
35 | Naming/MethodParameterName:
36 | Enabled: false
37 |
38 | Layout/LineLength:
39 | Enabled: false
40 |
41 | Metrics/BlockLength:
42 | Enabled: false
43 |
44 | Naming/HeredocDelimiterNaming:
45 | Enabled: false
46 |
47 | Style/IfUnlessModifier:
48 | Enabled: false
49 |
50 | Style/ClassVars:
51 | Enabled: false
52 |
53 | Style/MultilineBlockChain:
54 | Enabled: false
55 |
56 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ## [Unreleased]
2 |
3 | ## [0.1.0] - 2024-10-04
4 |
5 | - Initial release
6 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax = docker/dockerfile:experimental
2 |
3 | # IMPORTANT: build it this way to allow for privileged execution
4 | #
5 | # Docker daemon config should have the entitlement
6 | # ```json
7 | # { "builder": {"Entitlements": {"security-insecure": true }} }
8 | # ```
9 | # ```
10 | # DOCKER_BUILDKIT=1 docker build --allow security.insecure -t pgpm:local /path/to/pgpm
11 | # ```
12 |
13 | FROM fedora:41 AS pgpm
14 |
15 | RUN dnf -y install rpmlint ruby ruby-devel mock git gcc zlib-devel libyaml-devel
16 | # Pre-initialize mock roots
17 | COPY lib/pgpm/rpm/mock/configs configs
18 | RUN --security=insecure for file in $(find configs -name '*.cfg'); do for ver in "17 16 15 14 13"; \
19 | do mock --config-opts pgdg_version=$ver $file --init ; done; done
20 |
21 |
22 | # Pre-initialize gems. It may need an update later, but it'll save us time
23 | RUN mkdir -p /pgpm
24 | COPY lib /pgpm/lib
25 | COPY Gemfile /pgpm
26 | COPY pgpm.gemspec /pgpm
27 | COPY exe /pgpm/exe
28 | RUN chmod +x /pgpm/exe/*
29 | RUN cd /pgpm && gem build && gem install -n /usr/local/bin pgpm*.gem
30 | RUN rm -rf pgpm
31 |
32 | COPY containers.conf /etc/containers/containers.conf
33 |
34 | RUN rm -rf /run/containers/storage /run/libpod
35 |
36 | ENV QEMU_CPU max
37 |
38 |
39 | FROM pgpm AS pgpm-dev
40 |
41 | COPY . /pgpm
42 | RUN cd /pgpm && bundle install
43 | RUN rm -rf /pgpm
44 |
45 | VOLUME /pgpm
46 | WORKDIR /pgpm
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 |
5 | # Specify your gem's dependencies in pgpm.gemspec
6 | gemspec
7 |
8 | gem "rake", "~> 13.0"
9 |
10 | gem "minitest", "~> 5.16"
11 |
12 | gem "rubocop", "~> 1.21"
13 |
14 | gem "debug", "~> 1.9"
15 |
16 | gem "rbs", "~> 3.6"
17 |
18 | gem "csv", "~> 3.3"
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Postgres.pm
2 |
3 | **Postgres.pm** (aka **pgpm**) is a streamlined package manager designed to simplify the process of building and
4 | distributing Postgres extensions and packages.
5 |
6 | ## Key objectives
7 |
8 |
9 | Platform independence
10 |
11 | Postgres.pm is designed to deliver Postgres extensions
12 | in native packaging (such as RPM, DEB, OCI images, etc.)
13 | to support the broad variety of usage patterns.
14 |
15 |
16 |
17 | > [!NOTE]
18 | > Early release is targeting RHEL-based distributions using
19 | > official PGDG Postgres distributions with other options
20 | > coming up.
21 |
22 |
23 | Low-effort package maintenance
24 |
25 | Postgres.pm embraces the concept of inferences: based
26 | on given information, it'll figure out how to build the package
27 | if it fits into a set of pre-defined rules.
28 |
29 | New versions are automatically picked up and recognized.
30 |
31 | Package definition can be as simple as this – with no routine
32 | maintenace on new releases:
33 |
34 | ```ruby
35 |
36 | class Pgvector < Pgpm::Package
37 | github "pgvector/pgvector"
38 | end
39 | ```
40 |
41 |
42 |
43 |
44 | Package definition flexibility
45 |
46 | Packages definitions are defined in Ruby, allowing for near-infinite
47 | flexibility of their definition when necessary.
48 |
49 | This allows us to accomodate non-standard build and installation procedures
50 | with ease.
51 |
52 |
53 | ---
54 |
55 | ### Current Status
56 |
57 | We are preparing to start publishing RPM packages publicly soon. It's possible to build included packages manually.
58 |
59 |
60 | ### Development
61 |
62 | To build the packages, use the [exe/pgpm](exe/pgpm) script.
63 |
64 | Example:
65 |
66 | ```sh
67 | ./exe/pgpm build pgvector
68 | ```
69 |
70 | ## pgpm build command
71 |
72 | ```
73 | Usage:
74 | pgpm build PACKAGES...
75 |
76 | Arguments:
77 | PACKAGES # Package names (can include version with @, e.g., pgvector@1.0.0)
78 |
79 | Options:
80 | --pkgdir=VALUE # Directory to load packages from (default: "packages" if directory exists)
81 | --os=VALUE # OS name (default: auto-detected)
82 | --arch=VALUE # Target architecture (default: host architecture)
83 | --pgdist=VALUE # Target Postgres distribution (default: "pgdg")
84 | --pgver=VALUE # Target Postgres version (default: latest supported version)
85 | ```
86 |
87 | Examples:
88 |
89 | ```sh
90 | # Build specific version
91 | pgpm build pgvector@1.0.0
92 |
93 | # Build for specific Postgres version
94 | pgpm build pgvector --pgver=15
95 |
96 | # Build multiple packages
97 | pgpm build pgvector pg_cron
98 |
99 | # Build from custom package directory
100 | pgpm build pgvector --pkgdir=custom/packages
101 | ```
102 |
103 | ### Running pgpm build command via Official Docker Image
104 |
105 | Pull the official Docker image:
106 |
107 | ```sh
108 | docker pull ghcr.io/postgres-pm/pgpm:latest
109 | ```
110 |
111 | You can use the following command to build the packages:
112 |
113 | ```sh
114 | docker run --rm -it ghcr.io/postgres-pm/pgpm:latest pgpm build pgvector
115 | ```
116 |
117 | If using the development version (pgpm-dev stage), you can mount the current directory to the container:
118 |
119 | ```sh
120 | docker run --rm -it -v $(pwd):/pgpm ghcr.io/postgres-pm/pgpm:latest pgpm build pgvector
121 | ```
122 |
123 | ### Building the Docker Image
124 |
125 | To build the Docker image, use the following command:
126 |
127 | ```sh
128 | # Build and load the image into local Docker daemon
129 | docker buildx build --load --allow security.insecure -t pgpm:local .
130 | ```
131 |
132 | To use insecure builder, you can run the following commands:
133 |
134 | ```sh
135 | docker buildx create --name insecure-builder --driver-opt env.BUILDKIT_STEP_LOG_MAX_SIZE=-1 --buildkitd-flags '--allow-insecure-entitlement security.insecure'
136 | docker buildx use insecure-builder
137 | env DOCKER_BUILDKIT=1 docker build --allow security.insecure -t pgpm:local .
138 | ```
139 |
140 | Later, you can use the builder by running:
141 |
142 | ```sh
143 | env DOCKER_BUILDKIT=1 docker build --builder=insecure-builder --allow security.insecure -t pgpm:local .
144 | ```
145 |
146 | To run the image, use the following command:
147 |
148 | ```sh
149 | # If using the base pgpm image
150 | docker run --rm -it pgpm:local pgpm build pgvector
151 |
152 | # If using the development version (pgpm-dev stage)
153 | docker run --rm -it -v $(pwd):/pgpm pgpm:local ./exe/pgpm build pgvector
154 | ```
155 |
156 | To remove the builder, run the following command:
157 |
158 | ```sh
159 | docker buildx rm insecure-builder
160 | ```
161 |
162 | To remove the image, run the following command:
163 |
164 | ```sh
165 | docker rmi pgpm:local
166 | docker rmi ghcr.io/postgres-pm/pgpm:latest
167 | ```
168 |
169 | ### Troubleshooting
170 |
171 | #### Podman invocations terminate with exit code 137
172 |
173 | Make sure your machine has enough RAM. For `podman-machine` you might want to adjust it
174 | with
175 |
176 | ```shell
177 | podman machine stop
178 | podman machine set -m 16384 # for 16GB
179 | podman machine start
180 | ```
181 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "bundler/gem_tasks"
4 | require "minitest/test_task"
5 |
6 | Minitest::TestTask.create
7 |
8 | require "rubocop/rake_task"
9 |
10 | RuboCop::RakeTask.new
11 |
12 | task default: %i[test rubocop]
13 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require "bundler/setup"
5 | require "pgpm"
6 |
7 | # You can add fixtures and/or initialization code here to make experimenting
8 | # with your gem easier. You can also use a different console, if you like.
9 |
10 | require "irb"
11 | IRB.start(__FILE__)
12 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 | IFS=$'\n\t'
4 | set -vx
5 |
6 | bundle install
7 |
8 | # Do any other automated setup that you need to do here
9 |
--------------------------------------------------------------------------------
/containers.conf:
--------------------------------------------------------------------------------
1 | [containers]
2 | netns="host"
3 | userns="host"
4 | ipcns="host"
5 | utsns="host"
6 | cgroupns="host"
7 | cgroups="disabled"
8 | log_driver = "k8s-file"
9 | [engine]
10 | cgroup_manager = "cgroupfs"
11 | events_logger="file"
12 | runtime="crun"
--------------------------------------------------------------------------------
/exe/pgpm:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require "English"
5 | require "bundler/setup"
6 | require "pgpm"
7 | require "dry/cli"
8 | require "parallel"
9 | require "etc"
10 |
11 | module Pgpm
12 | module CLI
13 | module Commands
14 | extend Dry::CLI::Registry
15 |
16 | class Version < Dry::CLI::Command
17 | desc "Print version"
18 |
19 | def call(*)
20 | puts Pgpm::VERSION
21 | end
22 | end
23 |
24 | module SharedOptions
25 | def self.included(base)
26 | base.class_eval do
27 | option :pkgdir, type: :string, default: File.directory?("packages") ? "packages" : nil, desc: "Directory to load packages from"
28 | end
29 | end
30 | end
31 |
32 | class Build < Dry::CLI::Command
33 | desc "Build packages"
34 |
35 | include SharedOptions
36 |
37 | option :os, type: :string, default: Pgpm::OS.auto_detect&.name, desc: "OS name"
38 | option :arch, type: :string, default: Pgpm::Arch.host.name, desc: "Target architecture"
39 | option :pgdist, type: :string, default: "pgdg", desc: "Target Postgres distribution"
40 | option :pgver, type: :string, default: Pgpm::Postgres::Distribution.versions.last.to_s, desc: "Target Postgres version"
41 | option :path, type: :path, desc: "Override path to the source"
42 | argument :packages, type: :array, required: true, desc: "Package names"
43 |
44 | module ExtendedProc
45 | refine Proc do
46 | def and_then(callable)
47 | lambda do |*args|
48 | res1 = call(*args)
49 | res2 = callable.call(*args)
50 | return res1 + res2 if res1.is_a?(Array) && res2.is_a?(Array)
51 |
52 | res2
53 | end
54 | end
55 | end
56 | end
57 |
58 | using ExtendedProc
59 |
60 | # rubocop:disable Metrics/ParameterLists:
61 | def call(packages:, args: nil, os: nil, arch: nil, pgdist: nil, pgver: nil, pkgdir: nil, path: nil)
62 | _ = args
63 | _ = os
64 | _ = pgdist
65 |
66 | Pgpm.load_packages(pkgdir)
67 |
68 | # puts "There is no build support for OS distribution `#{os}`"
69 | # exit(1)
70 | pkgs = Parallel.flat_map(packages, in_threads: Etc.nprocessors) do |package|
71 | name, version = package.split("@")
72 | version ||= :latest
73 | p = Pgpm::Package[name]
74 | if p.nil?
75 | puts "Package #{name} not found"
76 | exit(1)
77 | end
78 | if p.contrib?
79 | puts "Can't build a contrib package"
80 | exit(1)
81 | end
82 | pkg = path.nil? ? p[version] : p.new(version).with_path(path)
83 | if pkg.nil?
84 | puts "Package #{name} with version #{version} not found"
85 | exit(1)
86 | end
87 | pkg
88 | end
89 |
90 | os = os ? Pgpm::OS.find(os) : Pgpm::OS.auto_detect
91 | arch = if arch
92 | Pgpm::Arch.new(arch)
93 | else
94 | Pgpm::Arch.host
95 | end
96 |
97 | pgver = Package::Version.new(pgver)
98 | matching_pgver = Postgres::Distribution.versions.sort.reverse.find { |v| v.satisfies?(">= #{pgver}") && v.satisfies?("< #{pgver.major + 1}") }
99 | unless matching_pgver
100 | puts "#{pgver} is not a known Postgres version"
101 | exit(1)
102 | end
103 |
104 | if os.is_a? Pgpm::OS::Debian
105 | puts "Building #{pkgs.map { |p| "#{p.name}@#{p.version}" }.join(", ")} for Postgres #{matching_pgver}"
106 | selected_pgdist = Postgres::RedhatBasedPgdg.new(matching_pgver.to_s)
107 |
108 | os.with_scope do
109 | arch.with_scope do
110 | selected_pgdist.with_scope do
111 | spec = nil
112 | pkgs.reduce(nil) do |_c, p|
113 | p = Pgpm::ScopedObject.new(p, os, arch)
114 | spec = p.to_deb_spec
115 | end
116 | builder = Pgpm::Deb::Builder.new(spec)
117 | builder.build
118 | end
119 | end
120 | end
121 | elsif os.is_a? Pgpm::OS::RedHat
122 | puts "Building #{pkgs.map { |p| "#{p.name}@#{p.version}" }.join(", ")} for Postgres #{matching_pgver}"
123 | selected_pgdist = Postgres::RedhatBasedPgdg.new(matching_pgver.to_s)
124 |
125 | os.with_scope do
126 | arch.with_scope do
127 | selected_pgdist.with_scope do
128 | pkgs = pkgs.flat_map(&:topologically_ordered_with_dependencies).uniq.reject(&:contrib?)
129 |
130 | b = pkgs.reduce(nil) do |c, p|
131 | if p.broken?
132 | puts "Can't build a broken package #{p.name}@#{p.version}"
133 | exit(1)
134 | end
135 | p = Pgpm::ScopedObject.new(p, os, arch)
136 | spec = p.to_rpm_spec
137 | builder = Pgpm::RPM::Builder.new(spec)
138 | src_builder = builder.source_builder
139 | p = c.nil? ? src_builder : c.and_then(src_builder)
140 | p.and_then(builder.versionless_builder)
141 | end
142 |
143 | srpms = b.call
144 | Pgpm::RPM::Builder.builder(srpms).call
145 | end
146 | end
147 | end
148 | else
149 | puts "#{os.name} is not a supported OS at this moment"
150 | exit(1)
151 | end
152 | end
153 |
154 | # rubocop:enable Metrics/ParameterLists:
155 | end
156 |
157 | class Search < Dry::CLI::Command
158 | include SharedOptions
159 |
160 | argument :query, type: :string, default: ".*", desc: "Search query"
161 | option :format, values: %w[text json], default: "text", desc: "Output format", aliases: ["-f"]
162 |
163 | def call(query:, args: nil, pkgdir: nil, format: nil)
164 | _ = args
165 |
166 | Pgpm.load_packages(pkgdir)
167 |
168 | query_regexp = Regexp.new(query, "i")
169 | if format == "json"
170 | puts "["
171 | end
172 |
173 | Parallel.filter_map(Pgpm::Package, in_threads: Etc.nprocessors) do |p|
174 | next if p.contrib?
175 |
176 | found = p.all_searchable_texts.any? do |t|
177 | t =~ query_regexp
178 | end
179 | next unless found
180 |
181 | output = case format
182 | when "json" then Oj.dump({
183 | name: p.package_name,
184 | summary: p.summary,
185 | description: p.description,
186 | license: p.license,
187 | versions: p.package_versions.map(&:to_s)
188 | }, mode: :strict)
189 | else
190 | "#{p.package_name}: #{p.description}"
191 | end
192 | puts output
193 | rescue StandardError
194 | warn "Error fetching #{p.package_name}: #{$ERROR_INFO.message}"
195 | end
196 |
197 | return unless format == "json"
198 |
199 | puts "]"
200 | end
201 | end
202 |
203 | register "version", Version, aliases: ["v", "-v", "--version"]
204 | register "build", Build
205 | register "search", Search
206 | end
207 | end
208 | end
209 |
210 | Dry::CLI.new(Pgpm::CLI::Commands).call
211 |
--------------------------------------------------------------------------------
/lib/pgpm.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "zeitwerk"
4 | require "pathname"
5 |
6 | class CustomInflector < Zeitwerk::GemInflector
7 | def camelize(basename, _abspath)
8 | # Specify your custom logic here
9 | # This tells Zeitwerk that 'rpm' should be 'RPM' and 'os' should be 'OS'
10 | case basename
11 | when "rpm"
12 | "RPM"
13 | when "os"
14 | "OS"
15 | when "pgxn"
16 | "PGXN"
17 | else
18 | super
19 | end
20 | end
21 | end
22 |
23 | module Pgpm
24 | end
25 |
26 | loader = Zeitwerk::Loader.for_gem
27 | loader.inflector = CustomInflector.new(__FILE__)
28 | loader.enable_reloading
29 | loader.setup
30 | loader.eager_load
31 |
32 | define_method(:reload!) do
33 | loader.reload
34 | loader.eager_load
35 | end
36 |
37 | define_method(:load_packages) do |path = nil|
38 | path ||= Pathname(File.dirname(__FILE__)).join("..", "packages")
39 | pkg_loader = Zeitwerk::Registry.loaders.find { |l| l.dirs.include?(path.to_s) }
40 | return pkg_loader if pkg_loader
41 |
42 | pkg_loader = Zeitwerk::Loader.new
43 | pkg_loader.push_dir(path)
44 | pkg_loader.enable_reloading
45 | pkg_loader.setup
46 | pkg_loader.eager_load
47 | pkg_loader
48 | end
49 |
--------------------------------------------------------------------------------
/lib/pgpm/arch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "rbconfig"
4 | require "lspace"
5 |
6 | module Pgpm
7 | class Arch
8 | def self.host
9 | new(RbConfig::CONFIG["host_cpu"])
10 | end
11 |
12 | def self.in_scope
13 | LSpace[:pgpm_target_arch]
14 | end
15 |
16 | def initialize(name)
17 | @name = name == "arm64" ? "aarch64" : name
18 | end
19 |
20 | attr_reader :name
21 |
22 | def with_scope(&block)
23 | LSpace.with(pgpm_target_arch: self) do
24 | block.yield
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/pgpm/aspects/inheritance_tracker.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Aspects
5 | module InheritanceTracker
6 | module ClassMethods
7 | def all_subclasses
8 | subclasses + subclasses.flat_map(&:all_subclasses)
9 | end
10 | end
11 |
12 | def self.included(base_class)
13 | base_class.extend(ClassMethods)
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/pgpm/cache.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "xdg"
4 |
5 | module Pgpm
6 | class Cache
7 | def self.directory
8 | XDG.new.cache_home.join("postgres.pm")
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/pgpm/commands.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "lspace"
4 |
5 | module Pgpm
6 | module Commands
7 | class Abstract
8 | def to_s
9 | raise "abstract implementation"
10 | end
11 | end
12 |
13 | class Make < Abstract
14 | def initialize(*args)
15 | @args = args
16 | super()
17 | end
18 |
19 | def to_s
20 | command = "make"
21 | command += " %{?_smp_mflags}" if Pgpm::OS.in_scope.is_a?(Pgpm::OS::RedHat)
22 | command += " #{@args.join(" ")}" unless @args.empty?
23 | command
24 | end
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/amcheck.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class Amcheck < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/auth_delay.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class AuthDelay < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/auto_explain.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class AutoExplain < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/basebackup_to_shell.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class BasebackupToShell < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/btree_gist.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class BtreeGist < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/dblink.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class Dblink < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/pgcrypto.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class Pgcrypto < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/plpython3u.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class Plpython3u < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/contrib/postgres_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Contrib
5 | class PostgresFdw < Pgpm::Package
6 | contrib_package
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/Dockerfile:
--------------------------------------------------------------------------------
1 | # syntax = docker/dockerfile:experimental
2 |
3 | # IMPORTANT: build it this way to allow for privileged execution
4 | #
5 | # Docker daemon config should have the entitlement
6 | # ```json
7 | # { "builder": {"Entitlements": {"security-insecure": true }} }
8 | # ```
9 | # ```
10 | # DOCKER_BUILDKIT=1 docker build --allow security.insecure -t IMAGE_NAME /path/to/pgpm
11 | # ```
12 |
13 | # This Dockerfile is used to build a Debian image, which includes pbuilder and
14 | # pbuilder chroot image with basic dependendencies needed for building most
15 | # packages already pre-installed.
16 |
17 | FROM docker.io/library/debian
18 |
19 | MAINTAINER PGPM Debian Maintainer debian.maintainer@postgres.pm
20 |
21 | VOLUME /proc
22 | ARG DEBIAN_FRONTEND=noninteractive
23 | RUN apt update
24 | RUN apt install -y build-essential pbuilder fakeroot fakechroot
25 | RUN echo 'MIRRORSITE=http://deb.debian.org/debian' > /etc/pbuilderrc
26 | RUN echo 'AUTO_DEBSIGN=${AUTO_DEBSIGN:-no}' > /root/.pbuilderrc
27 | RUN echo 'HOOKDIR=/var/cache/pbuilder/hooks' >> /root/.pbuilderrc
28 | RUN --security=insecure pbuilder create
29 |
30 | COPY pbuilder_install_script.sh /root/pbuilder_install_script.sh
31 | RUN --security=insecure pbuilder execute --save-after-exec /root/pbuilder_install_script.sh
32 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/builder.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "English"
4 | require "debug"
5 |
6 | module Pgpm
7 | module Deb
8 | class Builder
9 | def initialize(spec)
10 | @spec = spec
11 | @container_name = "pgpm-debian_build-#{Time.now.to_i}_#{rand(10_000)}"
12 | @pgpm_dir = Dir.mktmpdir
13 | end
14 |
15 | def build
16 | pull_image
17 | start_container
18 | patch_pbuilder
19 |
20 | prepare_versioned_source
21 | generate_deb_src_files(:versioned)
22 | run_build(:versioned)
23 | copy_build_from_container(:versioned)
24 |
25 | prepare_default_source
26 | generate_deb_src_files(:default)
27 | run_build(:default)
28 | copy_build_from_container(:default)
29 |
30 | cleanup
31 | end
32 |
33 | private
34 |
35 | # Depends on postgres version and arch
36 | def image_name
37 | "quay.io/qount25/pgpm-debian-pg#{@spec.package.postgres_major_version}-#{@spec.arch}"
38 | end
39 |
40 | def prepare_versioned_source
41 | puts "Preparing build..."
42 | puts " Creating container dir structure..."
43 | Dir.mkdir "#{@pgpm_dir}/source-versioned"
44 | Dir.mkdir "#{@pgpm_dir}/out"
45 |
46 | puts " Downloading and unpacking sources to #{@pgpm_dir}"
47 |
48 | fn = nil
49 | @spec.sources.map do |src|
50 | srcfile = File.join(@pgpm_dir.to_s, src.name)
51 | File.write(srcfile, src.read)
52 | fn = src.name
53 | end
54 |
55 | system("tar -xf #{@pgpm_dir}/#{fn} -C #{@pgpm_dir}/source-versioned/")
56 | FileUtils.remove("#{@pgpm_dir}/#{fn}")
57 |
58 | untar_dir_entries = Dir.entries("#{@pgpm_dir}/source-versioned/").reject do |entry|
59 | [".", ".."].include?(entry)
60 | end
61 |
62 | if untar_dir_entries.size == 1
63 | entry = untar_dir_entries[0]
64 | if File.directory?("#{@pgpm_dir}/source-versioned/#{entry}")
65 | FileUtils.mv "#{@pgpm_dir}/source-versioned/#{entry}", "#{@pgpm_dir}/"
66 | FileUtils.remove_dir "#{@pgpm_dir}/source-versioned/"
67 | FileUtils.mv "#{@pgpm_dir}/#{entry}", "#{@pgpm_dir}/source-versioned"
68 | end
69 | end
70 |
71 | ["prepare_artifacts.sh"].each do |f|
72 | script_fn = File.expand_path("#{__dir__}/scripts/#{f}")
73 | FileUtils.cp script_fn, "#{@pgpm_dir}/source-versioned/"
74 | end
75 | end
76 |
77 | def prepare_default_source
78 | Dir.mkdir "#{@pgpm_dir}/source-default"
79 |
80 | # 1. All pbuilder builds are in /var/cache/pbuilder/build. At this point
81 | # there's only one build, but we don't know what the directory is named
82 | # (the name is usually some numbers). So we just pick the first (and only)
83 | # entry at this location and this is our build dir.
84 | pbuilds_dir = "/var/cache/pbuilder/build"
85 | cmd = "ls -U #{pbuilds_dir} | head -1"
86 | build_dir = `podman exec #{@container_name} /bin/bash -c '#{cmd}'`.strip
87 | puts "BUILD DIR IS: #{pbuilds_dir}/#{build_dir}"
88 |
89 | # 2. Determine the name of the .control file inside the versioned build
90 | deb_dir = "#{pbuilds_dir}/#{build_dir}/build/#{@spec.deb_pkg_name(:versioned)}-0/debian/#{@spec.deb_pkg_name(:versioned)}"
91 | control_fn = "#{deb_dir}/usr/share/postgresql/#{@spec.package.postgres_major_version}/extension/#{@spec.package.extension_name}--#{@spec.package.version}.control"
92 |
93 | # 3. Copy .control file to the source-default dir
94 | puts "Copying #{control_fn} into /root/pgpm/source-default/"
95 | target_control_fn = "/root/pgpm/source-default/#{@spec.package.extension_name}.control"
96 | cmd = "cp #{control_fn} #{target_control_fn}"
97 | system("podman exec #{@container_name} /bin/bash -c '#{cmd}'")
98 |
99 | ["install_default_control.sh"].each do |fn|
100 | script_fn = File.expand_path("#{__dir__}/scripts/#{fn}")
101 | FileUtils.cp script_fn, "#{@pgpm_dir}/source-default/"
102 | end
103 | end
104 |
105 | def pull_image
106 | puts "Checking if podman image exists..."
107 | # Check if image exists
108 | system("podman image exists #{image_name}")
109 | if $CHILD_STATUS.to_i.positive? # image doesn't exist -- pull image from a remote repository
110 | puts " No. Pulling image #{image_name}..."
111 | system("podman pull #{image_name}")
112 | else
113 | puts " Yes, image #{image_name} already exists! OK"
114 | end
115 | end
116 |
117 | def generate_deb_src_files(pkg_type = :versioned)
118 | puts "Generating debian files..."
119 | Dir.mkdir "#{@pgpm_dir}/source-#{pkg_type}/debian"
120 | %i[changelog control copyright files rules].each do |f|
121 | puts " -> #{@pgpm_dir}/source-#{pkg_type}/debian/#{f}"
122 | File.write "#{@pgpm_dir}/source-#{pkg_type}/debian/#{f}", @spec.generate(f, pkg_type)
123 | end
124 | File.chmod 0o740, "#{@pgpm_dir}/source-#{pkg_type}/debian/rules" # rules file must be executable
125 | end
126 |
127 | def start_container
128 | # podman create options
129 | create_opts = " -v #{@pgpm_dir}:/root/pgpm"
130 | create_opts += ":z" if selinux_enabled?
131 | create_opts += " --privileged --tmpfs /tmp"
132 | create_opts += " --name #{@container_name} #{image_name}"
133 |
134 | puts " Creating and starting container #{@container_name} & running pbuilder"
135 | system("podman create -it #{create_opts}")
136 | exit(1) if $CHILD_STATUS.to_i.positive?
137 | system("podman start #{@container_name}")
138 | exit(1) if $CHILD_STATUS.to_i.positive?
139 | end
140 |
141 | # Prevents clean-up after pbuilder finishes. There's no option
142 | # in pbuilder to do it, so we have to patch it manually. The issue is
143 | # with pbuilder not being able to delete some directories (presumably,
144 | # due to directory names starting with ".") and returning error.
145 | #
146 | # This little patch avoids the error by returning from the python cleanup
147 | # function early -- because the package itself is built successfully and
148 | # we don't actually care that pbuilder is unable to clean something up.
149 | # The container is going to be removed anyway, so it's even less work as
150 | # a result.
151 | def patch_pbuilder
152 | cmd = "sed -E -i \"s/(^function clean_subdirectories.*$)/\\1\\n return/g\" /usr/lib/pbuilder/pbuilder-modules"
153 | system("podman exec #{@container_name} /bin/bash -c '#{cmd}'")
154 | end
155 |
156 | def run_build(pkg_type = :versioned)
157 | dsc_fn = "#{@spec.deb_pkg_name(pkg_type)}_0-1.dsc"
158 | deb_fn = "#{@spec.deb_pkg_name(pkg_type)}_0-1_#{@spec.arch}.deb"
159 |
160 | cmds = []
161 | cmds << "dpkg-buildpackage --build=source -d" # -d flag helps with dependencies error
162 | cmds << "fakeroot pbuilder build ../#{dsc_fn}"
163 | cmds << "mv /var/cache/pbuilder/result/#{deb_fn} /root/pgpm/out/"
164 |
165 | puts " Building package with pbuilder..."
166 | cmds.each do |cmd|
167 | system("podman exec -w /root/pgpm/source-#{pkg_type} #{@container_name} /bin/bash -c '#{cmd}'")
168 | exit(1) if $CHILD_STATUS.to_i.positive?
169 | end
170 | end
171 |
172 | def copy_build_from_container(pkg_type = :versioned)
173 | puts "Copying .deb file from podman container into current directory..."
174 | deb_fn = "#{@spec.deb_pkg_name(pkg_type)}_0-1_#{@spec.arch}.deb"
175 | deb_copy_fn = "#{@spec.deb_pkg_name(pkg_type)}_#{@spec.arch}.deb"
176 | FileUtils.cp("#{@pgpm_dir}/out/#{deb_fn}", "#{Dir.pwd}/#{deb_copy_fn}")
177 | end
178 |
179 | def cleanup
180 | puts "Cleaning up..."
181 |
182 | puts " Stopping destroying podman container: #{@container_name}"
183 | system("podman container stop #{@container_name}")
184 | system("podman container rm #{@container_name}")
185 |
186 | # Remove temporary files
187 | #
188 | # Make sure @pgpm_dir starts with "/tmp/" or we may accidentally
189 | # delete something everything! You can never be sure!
190 | if @pgpm_dir.start_with?("/tmp/")
191 | puts " Removing temporary files in #{@pgpm_dir}"
192 | FileUtils.rm_rf(@pgpm_dir)
193 | else
194 | puts "WARNING: will not remove temporary files, strange path: \"#{@pgpm_dir}\""
195 | end
196 | end
197 |
198 | # Needed because SELinux requires :z suffix for mounted directories to
199 | # be accessible -- otherwise we get "Permission denied" when cd into a
200 | # mounted dir inside the container.
201 | def selinux_enabled?
202 | # This returns true or false by itself
203 | system("sestatus | grep 'SELinux status' | grep -o 'enabled'")
204 | end
205 | end
206 | end
207 | end
208 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/pbuilder_install_script.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | apt update
3 | DEBIAN_FRONTEND=noninteractive apt -y install build-essential curl lsb-release ca-certificates
4 |
5 | ### PostgreSQL installation
6 | #
7 | install -d /usr/share/postgresql-common/pgdg
8 | curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
9 |
10 | # Create the repository configuration file:
11 | sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
12 |
13 | # Update the package lists:
14 | apt update
15 |
16 | # Install the latest version of PostgreSQL:
17 | # If you want a specific version, use 'postgresql-16' or similar instead of 'postgresql'
18 | apt -y install postgresql-17 postgresql-server-dev-17 postgresql-common
19 | #
20 | ### END OF PostgreSQL installation
21 |
22 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/scripts/install_default_control.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ext_dir="$PGPM_INSTALL_ROOT/$(pg_config --sharedir)/extension"
4 | control_fn="$ext_dir/$PGPM_EXTENSION_NAME.control"
5 |
6 | echo "Creating extension dir: $ext_dir"
7 | mkdir -p "$ext_dir"
8 |
9 | echo "Creating control file: $control_fn"
10 | cp "$PGPM_BUILDROOT/$PGPM_EXTENSION_NAME.control" "$ext_dir/"
11 | echo >> "$control_fn"
12 | echo "default_version = '$PGPM_EXTENSION_VERSION'" >> "$control_fn"
13 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/scripts/pg_config.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # Ensure PG_CONFIG is set
4 | if [[ -z "$PG_CONFIG" ]]; then
5 | echo "Error: PG_CONFIG is not set."
6 | exit 1
7 | fi
8 |
9 | # Wrapper function for pg_config
10 | pg_config_wrapper() {
11 | "$PG_CONFIG" "$@" | while read -r line; do
12 | if [[ -n "$PGPM_REDIRECT_TO_BUILDROOT" && -f "$line" || -d "$line" ]]; then
13 | echo "$PGPM_INSTALL_ROOT$line"
14 | else
15 | echo "$line"
16 | fi
17 | done
18 | }
19 |
20 | # Call the wrapper function with the arguments passed to the script
21 | pg_config_wrapper "$@"
22 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/scripts/prepare_artifacts.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | #set -xe
4 |
5 | new_extension_so=
6 |
7 | PG_CONFIG="${PG_CONFIG:-"pg_config"}"
8 |
9 | install_root=$PGPM_INSTALL_ROOT
10 |
11 | for file in $(find $PGPM_BUILDROOT -name '*.so'); do
12 | filename=$(basename "$file")
13 | if [[ "$filename" == "${PGPM_EXTENSION_NAME}.so" ]]; then
14 | extension_so=$filename
15 | dir=$(dirname "$file")
16 | extension_dirname=${dir#"$PGPM_BUILDROOT"}
17 | new_extension_so=$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.so
18 | break
19 | fi
20 | done
21 |
22 | extdir=$install_root$($PG_CONFIG --sharedir)/extension
23 |
24 | # control files
25 | default_control=$extdir/$PGPM_EXTENSION_NAME.control
26 | versioned_control=$extdir/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.control
27 | controls=("$default_control" "$versioned_control")
28 |
29 | function rename_so() {
30 | mv "$install_root$extension_dirname/$extension_so" \
31 | "$install_root$extension_dirname/$new_extension_so"
32 | }
33 |
34 | function change_name_in_controls() {
35 | echo "CHANGING EXTENSION NAME IN CONTROL FILES"
36 | echo "----------------------------------------"
37 | for control in "${controls[@]}"; do
38 | if [[ -f "$control" ]]; then
39 | echo "$control"
40 | # extension.so
41 | sed -i "s|${extension_so}'|${new_extension_so}'|g" "$control"
42 | # extension
43 | sed -i "s|${extension_so%".so"}'|${new_extension_so%".so"}'|g" "$control"
44 | fi
45 | done
46 | }
47 |
48 | function rename_sql_files() {
49 | echo "RENAMING EXTENSION SQL FILES"
50 | echo "----------------------------"
51 | for sql_file in $(find $install_root -name '*.sql' -type f); do
52 | echo "$sql_file"
53 | # extension.so
54 | sed -i "s|/${extension_so}'|/${new_extension_so}'|g" "$sql_file"
55 | # extension
56 | sed -i "s|/${extension_so%".so"}'|/${new_extension_so}'|g" "$sql_file"
57 | done
58 | }
59 |
60 | function rename_bitcode() {
61 | echo "RENAMING BITCODE"
62 | echo "----------------"
63 |
64 | pkglibdir=$install_root$($PG_CONFIG --pkglibdir)
65 | bitcode_extension=$pkglibdir/bitcode/${extension_so%".so"}
66 | bitcode_index=$pkglibdir/bitcode/${extension_so%".so"}.index.bc
67 |
68 | if [[ -d "${bitcode_extension}" ]]; then
69 | echo "$bitcode_extension"
70 | mv "$bitcode_extension" "$pkglibdir/bitcode/${new_extension_so%".so"}"
71 | fi
72 |
73 | if [[ -f "${bitcode_index}" ]]; then
74 | echo "$bitcode_index"
75 | mv "${bitcode_index}" "$pkglibdir/bitcode/${new_extension_so%".so"}.index.bc"
76 | fi
77 | }
78 |
79 | function rename_includes() {
80 | includedir=$install_root$($PG_CONFIG --includedir-server)
81 | echo "RENAMING INCLUDES"
82 | echo "-----------------"
83 | if [[ -d "${includedir}/extension/$PGPM_EXTENSION_NAME" ]]; then
84 | echo "$includedir"
85 | versioned_dir=${includedir}/extension/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION
86 | mkdir -p "$versioned_dir"
87 | mv "${includedir}/extension/$PGPM_EXTENSION_NAME" "$versioned_dir"
88 | fi
89 | }
90 |
91 | # Make sure we don't build a default control as it belongs
92 | # to another package
93 | function handle_default_control() {
94 | if [[ -f "$default_control" ]]; then
95 | if [[ -f "$versioned_control" ]]; then
96 | # We don't need default control if versioned is present
97 | rm -f "$default_control"
98 | else
99 | # Default becomes versioned
100 | mv "$default_control" "$versioned_control"
101 | # Don't need default_version
102 | sed -i '/default_version/d' "$versioned_control"
103 | fi
104 | fi
105 | }
106 |
107 | if [[ -n "$new_extension_so" ]]; then
108 | rename_so
109 | change_name_in_controls
110 | rename_sql_files
111 | rename_bitcode
112 | rename_incluides
113 | fi
114 |
115 | handle_default_control
116 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "digest"
4 | require "open-uri"
5 | require "erb"
6 |
7 | module Pgpm
8 | module Deb
9 | class Spec
10 | attr_reader :package, :release, :postgres_version, :postgres_distribution
11 |
12 | def initialize(package)
13 | @postgres_distribution = Pgpm::Postgres::Distribution.in_scope
14 | @package = package
15 | @package.postgres_major_version = @postgres_distribution.major_version
16 | @release = 1
17 | end
18 |
19 | def sources
20 | @package.sources
21 | end
22 |
23 | def generate(template_name, pkg_type = :versioned)
24 | fn = "#{__dir__}/templates/#{template_name}.erb"
25 | raise "No such template: #{fn}" unless File.exist?(fn)
26 |
27 | erb = ERB.new(File.read(fn))
28 |
29 | # Uses pkg_type parameter (which is in scope) to generate
30 | # debian/* files for versionless and main packages.
31 | erb.result(binding)
32 | end
33 |
34 | def source_version
35 | v = @package.version.to_s
36 | v.match(/\Z\d+\.\d+\Z/) ? "#{v}.0" : v
37 | end
38 |
39 | def deb_pkg_name(type = :versioned)
40 | if type == :versioned
41 | "#{@package.name.gsub("_", "-")}+#{source_version}-pg#{@package.postgres_major_version}"
42 | else
43 | "#{@package.name.gsub("_", "-")}-pg#{@package.postgres_major_version}"
44 | end
45 | end
46 |
47 | def arch
48 | # https://memgraph.com/blog/ship-it-on-arm64-or-is-it-aarch64
49 | # Debian suffixes are "amd64" and "arm64". Here we translate:
50 | case Pgpm::Arch.in_scope.name
51 | when "amd64", "x86_64"
52 | "amd64"
53 | when "aarch64", "arm64"
54 | "arm64"
55 | end
56 | end
57 |
58 | def cmds_if_not_empty(cmds, else_echo)
59 | return "\techo \"#{else_echo}\"" if cmds.nil? || cmds.empty?
60 |
61 | cmds.map!(&:to_s)
62 | cmds.map! { |c| c.gsub("$", "$$") }
63 | cmds.join("\t")
64 | end
65 | end
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/templates/changelog.erb:
--------------------------------------------------------------------------------
1 | <%= deb_pkg_name(pkg_type) %> (0-1) stable; urgency=medium
2 |
3 | * Version <%= pkg_type == :versioned ? 1 : source_version %> package release.
4 |
5 | -- PGPM Debian maintainer <%= Time.now.strftime('%a, %d %b %Y %H:%M:%S %z')%>
6 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/templates/control.erb:
--------------------------------------------------------------------------------
1 | Source: <%= deb_pkg_name(pkg_type) %>
2 | Description: <%= self.package.description %>
3 | Section: libs
4 | Priority: optional
5 | Maintainer: PGPM Debian maintainer
6 | Rules-Requires-Root: no
7 | Build-Depends: debhelper-compat (= 13), <%= self.package.build_dependencies.join(", ") %>
8 | Standards-Version: 4.6.2
9 |
10 | Package: <%= deb_pkg_name(pkg_type) %>
11 | Depends: <%= pkg_type == :versioned ? self.package.dependencies.join(", ") : deb_pkg_name(:versioned) %>
12 | Section: libdevel
13 | Architecture: <%= arch %>
14 | Description: <%= self.package.description %>
15 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/templates/copyright.erb:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Source:
3 | Upstream-Name: <%= self.package.name %>-<%= self.package.version.to_s %>
4 | Upstream-Contact:
5 |
6 | Files:
7 | *
8 | Copyright:
9 | <%= self.package.license %>
10 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/templates/files.erb:
--------------------------------------------------------------------------------
1 | <%= deb_pkg_name(pkg_type) %>_source.buildinfo libs optional
2 |
--------------------------------------------------------------------------------
/lib/pgpm/deb/templates/rules.erb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 |
3 | export DEB_BUILDDIR = $(CURDIR)
4 | export PGPM_BUILDROOT = $(CURDIR)
5 | export PG_CONFIG = $(shell /usr/bin/which pg_config)
6 | export PGPM_EXTENSION_NAME = "<%= self.package.extension_name %>"
7 | export PGPM_EXTENSION_VERSION = "<%= self.package.version %>"
8 | export PGPM_INSTALL_ROOT = "$(CURDIR)/debian/<%= deb_pkg_name(pkg_type) %>"
9 |
10 | <% if pkg_type == :versioned %>
11 | %:
12 | dh $@
13 |
14 | override_dh_auto_configure:
15 | echo " --> configuring"
16 | <%= cmds_if_not_empty self.package.configure_steps, '...nothing to configure' %>
17 |
18 | override_dh_auto_build:
19 | echo " --> building"
20 | <%= cmds_if_not_empty self.package.build_steps, '...nothing to build' %>
21 |
22 | override_dh_auto_install:
23 | echo " --> installing"
24 | dh_auto_install
25 | <%= cmds_if_not_empty self.package.install_steps, '...no custom install steps' %>
26 | chmod +x "$$DEB_BUILDDIR/prepare_artifacts.sh"
27 | find $$PGPM_INSTALL_ROOT -type f | sort - | sed 's|^$$PGPM_INSTALL_ROOT||' > .pgpm_before | sort
28 | ./prepare_artifacts.sh
29 |
30 | <% else %>
31 | %:
32 | dh $@
33 |
34 | override_dh_auto_install:
35 | dh_auto_install
36 | echo " --> INSTALL"
37 | chmod +x "$$DEB_BUILDDIR/install_default_control.sh"
38 | ./install_default_control.sh
39 |
40 | <% end %>
41 |
--------------------------------------------------------------------------------
/lib/pgpm/on_demand_file.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class OnDemandFile
5 | attr_reader :name
6 |
7 | def initialize(name, proc)
8 | @name = name
9 | @proc = proc
10 | end
11 |
12 | private
13 |
14 | def respond_to_missing?(symbol)
15 | @io ||= @proc.call
16 | @io.respond_to?(symbol)
17 | end
18 |
19 | def method_missing(name, *args)
20 | @io ||= @proc.call
21 | @io.send(name, *args)
22 | end
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/lib/pgpm/os.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "lspace"
4 |
5 | module Pgpm
6 | module OS
7 | class Base
8 | attr_reader :arch
9 |
10 | include Pgpm::Aspects::InheritanceTracker
11 |
12 | def self.name
13 | "unknown"
14 | end
15 |
16 | def name
17 | self.class.name
18 | end
19 |
20 | def self.kind
21 | "unknown"
22 | end
23 |
24 | def kind
25 | self.class.kind
26 | end
27 |
28 | def self.builder
29 | nil
30 | end
31 |
32 | def with_scope(&block)
33 | LSpace.with(pgpm_target_operating_system: self) do
34 | block.yield
35 | end
36 | end
37 | end
38 |
39 | def self.auto_detect
40 | if RUBY_PLATFORM =~ /linux$/
41 | Pgpm::OS::Linux.auto_detect
42 | else
43 | RUBY_PLATFORM =~ /darwin/
44 | Pgpm::OS::Darwin.auto_detect
45 | end
46 | end
47 |
48 | def self.find(name)
49 | Base.all_subclasses.find { |klass| klass.name == name }&.new
50 | end
51 |
52 | def self.in_scope
53 | LSpace[:pgpm_target_operating_system]
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/lib/pgpm/os/darwin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module OS
5 | class Darwin < Pgpm::OS::Unix
6 | def self.name
7 | "darwin"
8 | end
9 |
10 | def self.auto_detect
11 | new
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/pgpm/os/debian.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "rbconfig"
4 |
5 | module Pgpm
6 | module OS
7 | class Debian < Pgpm::OS::Linux
8 | def self.auto_detect
9 | # TODO: distinguish between flavors of Debian
10 | Debian12.new
11 | end
12 |
13 | def self.name
14 | "debian"
15 | end
16 |
17 | def mock_config; end
18 | end
19 |
20 | class Debian12 < Pgpm::OS::Debian
21 | def self.name
22 | "debian-12"
23 | end
24 |
25 | def self.builder
26 | Pgpm::Debian::Builder
27 | end
28 |
29 | def mock_config
30 | "debian-12-#{Pgpm::Arch.in_scope.name}+pgdg"
31 | end
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/lib/pgpm/os/linux.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module OS
5 | class Linux < Pgpm::OS::Unix
6 | def self.auto_detect
7 | return unless File.exist?("/etc/redhat-release")
8 |
9 | RedHat.auto_detect
10 | end
11 |
12 | def self.name
13 | "linux"
14 | end
15 |
16 | def kind
17 | "linux"
18 | end
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/pgpm/os/red_hat.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "rbconfig"
4 |
5 | module Pgpm
6 | module OS
7 | class RedHat < Pgpm::OS::Linux
8 | def self.auto_detect
9 | # TODO: distinguish between flavors of RedHat
10 | RockyEPEL9.new
11 | end
12 |
13 | def self.name
14 | "redhat"
15 | end
16 |
17 | def mock_config; end
18 | end
19 |
20 | class RockyEPEL9 < Pgpm::OS::RedHat
21 | def self.name
22 | "rocky+epel-9"
23 | end
24 |
25 | def self.builder
26 | Pgpm::RPM::Builder
27 | end
28 |
29 | def mock_config
30 | "rocky+epel-9-#{Pgpm::Arch.in_scope.name}+pgdg"
31 | end
32 | end
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/lib/pgpm/os/unix.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module OS
5 | class Unix < Pgpm::OS::Base
6 | def self.name
7 | "unix"
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/pgpm/package.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "dry/inflector"
4 |
5 | module Pgpm
6 | class Package
7 | include Pgpm::Aspects::InheritanceTracker
8 | include AbstractPackage
9 | include Source
10 | include Naming
11 | include Metadata
12 | include Dependencies
13 | include Git
14 | include GitHub
15 | include PGXN
16 | include Versioning
17 | include Subscripting
18 | include Enumerating
19 | include Native
20 | include Building
21 | include Make
22 | include Rust
23 | include Initialization
24 | include Packaging
25 | include Contrib
26 | include WithPath
27 |
28 | def inspect
29 | "#<#{self.class}:#{self.class.package_name} #{version}>"
30 | end
31 |
32 | abstract_package
33 | end
34 | end
35 |
--------------------------------------------------------------------------------
/lib/pgpm/package/abstract_package.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module AbstractPackage
6 | module ClassMethods
7 | def abstract_package?
8 | @is_abstract_package || false
9 | end
10 |
11 | protected
12 |
13 | def abstract_package
14 | @is_abstract_package = true
15 | end
16 | end
17 |
18 | def self.included(base_class)
19 | base_class.extend(ClassMethods)
20 | end
21 | end
22 | end
23 | end
24 |
--------------------------------------------------------------------------------
/lib/pgpm/package/building.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Building
6 | def configure_steps
7 | []
8 | end
9 |
10 | def source_url_directory_name
11 | nil
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/pgpm/package/contrib.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Contrib
6 | def contrib?
7 | self.class.instance_variable_get(:@contrib)
8 | end
9 |
10 | module ClassMethods
11 | def contrib_package
12 | @contrib = true
13 | end
14 |
15 | def package_name(exclude_namespace: false)
16 | if contrib?
17 | super(exclude_namespace: true)
18 | else
19 | super
20 | end
21 | end
22 |
23 | def contrib?
24 | @contrib
25 | end
26 |
27 | def package_versions
28 | if contrib?
29 | Class.new do
30 | include Enumerable
31 |
32 | def include?(_version)
33 | true
34 | end
35 |
36 | def empty?
37 | false
38 | end
39 |
40 | def each
41 | yield "*"
42 | end
43 | end.new
44 | else
45 | super
46 | end
47 | end
48 | end
49 |
50 | def self.included(base_class)
51 | base_class.extend(ClassMethods)
52 | end
53 | end
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/lib/pgpm/package/dependencies.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "tsort"
4 |
5 | module Pgpm
6 | class Package
7 | module Dependencies
8 | attr_accessor :postgres_major_version
9 |
10 | def build_dependencies
11 | case Pgpm::OS.in_scope.class.name
12 | when "debian", "ubuntu"
13 | deps = [
14 | "postgresql-#{postgres_major_version}",
15 | "postgresql-server-dev-#{postgres_major_version}",
16 | "postgresql-common"
17 | ]
18 | if native?
19 | deps << "build-essential"
20 | end
21 | when "rocky+epel-9", "redhat", "fedora"
22 | []
23 | end
24 | end
25 |
26 | def dependencies
27 | case Pgpm::OS.in_scope.class.name
28 | when "debian", "ubuntu"
29 | ["postgresql-#{postgres_major_version}"]
30 | when "rocky+epel-9", "redhat", "fedora"
31 | []
32 | end
33 | end
34 |
35 | def requires
36 | []
37 | end
38 |
39 | def all_requirements
40 | requires.flat_map { |r| [r, *r.all_requirements] }.uniq
41 | end
42 |
43 | def topologically_ordered_with_dependencies
44 | TopologicalPackageSorter.new([self, *all_requirements]).sorted_packages
45 | end
46 |
47 | class TopologicalPackageSorter
48 | include TSort
49 |
50 | def initialize(packages)
51 | @packages = packages.each_with_object({}) do |pkg, hash|
52 | hash[pkg.name] = pkg
53 | end
54 | end
55 |
56 | def tsort_each_node(&block)
57 | @packages.each_key(&block)
58 | end
59 |
60 | def tsort_each_child(node, &block)
61 | package = @packages[node]
62 | package.requires.each { |req| block.call(req) if @packages.key?(req) }
63 | end
64 |
65 | def sorted_packages
66 | tsort.map { |name| @packages[name] }.reverse
67 | end
68 | end
69 |
70 | def c_files_present?
71 | Dir.glob("*.c", base: source).any?
72 | end
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/lib/pgpm/package/enumerating.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Enumerating
6 | def self.included(base_class)
7 | class << base_class
8 | include Enumerable
9 | def each(&block)
10 | if self == Pgpm::Package
11 | all_subclasses.each(&block)
12 | else
13 | package_versions.map { |v| new(v) }.each(&block)
14 | end
15 | end
16 | end
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/pgpm/package/git.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "git"
4 |
5 | module Pgpm
6 | class Package
7 | module Git
8 | Config = Data.define(:url, :download_version_tags, :tag_prefix, :version_pattern)
9 |
10 | module ClassMethods
11 | attr_reader :git_config
12 |
13 | module Methods
14 | SEMVER = /(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/
15 |
16 | def package_versions
17 | if !git_config.download_version_tags
18 | super
19 | else
20 | prefix_re = Regexp.quote(git_config.tag_prefix.to_s)
21 | prefix_re = git_config.tag_prefix if git_config.tag_prefix.is_a?(Regexp)
22 | git_term_prompt = ENV["GIT_TERMINAL_PROMPT"]
23 | ENV["GIT_TERMINAL_PROMPT"] = "0"
24 | begin
25 | @tags ||=
26 | ::Git.ls_remote(git_config.url)["tags"].keys
27 | .filter { |key| !key.end_with?("^{}") }
28 | .filter { |key| key.match?(/^(#{prefix_re})#{git_config.version_pattern || SEMVER}/) }
29 | rescue StandardError
30 | @tags ||= []
31 | end
32 | ENV["GIT_TERMINAL_PROMPT"] = git_term_prompt
33 | versions = @tags.map { |tag| tag.gsub(/^(#{prefix_re})/, "") }.map { |v| Pgpm::Package::Version.new(v) }
34 | @tag_versions = Hash[@tags.zip(versions)]
35 | @version_tags = Hash[versions.zip(@tags)]
36 | versions
37 | end
38 | end
39 | end
40 |
41 | def git(url, download_version_tags: true, tag_prefix: /v?/, version_pattern: nil)
42 | @git_config = Config.new(url:, download_version_tags:, tag_prefix:, version_pattern:)
43 | extend Methods
44 | end
45 | end
46 |
47 | def version_git_tag
48 | self.class.package_versions if self.class.instance_variable_get(:@version_tags).nil?
49 | version_tags = self.class.instance_variable_get(:@version_tags) || {}
50 | version_tags[version]
51 | end
52 |
53 | def version_git_commit
54 | nil
55 | end
56 |
57 | def source
58 | directory = Pgpm::Cache.directory.join(name, version.to_s)
59 | tag = version_git_tag
60 | commit = version_git_commit
61 | directory = Pgpm::Cache.directory.join(name, commit) if commit
62 | if File.directory?(directory) && File.directory?(directory.join(".git"))
63 | directory
64 | elsif File.directory?(directory)
65 | raise "Unexpected non-git directory #{directory}"
66 | else
67 | if tag
68 | ::Git.clone(self.class.git_config.url, directory, depth: 1, branch: version_git_tag)
69 | elsif commit
70 | g = ::Git.clone(self.class.git_config.url, directory)
71 | g.checkout("checkout-#{commit}", new_branch: true, start_point: commit)
72 | else
73 | ::Git.clone(self.class.git_config.url, directory, depth: 1)
74 | end
75 | directory
76 | end
77 | end
78 |
79 | def release_date
80 | ::Git.open(source).log.first.date
81 | end
82 |
83 | def self.included(base_class)
84 | base_class.extend(ClassMethods)
85 | end
86 | end
87 | end
88 | end
89 |
--------------------------------------------------------------------------------
/lib/pgpm/package/git_hub.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "open-uri"
4 |
5 | module Pgpm
6 | class Package
7 | module GitHub
8 | Config = Data.define(:name, :download_version_tags)
9 |
10 | module Methods
11 | def sources
12 | commit = version_git_tag || version_git_commit
13 | [Pgpm::OnDemandFile.new("#{version}.tar.gz", lambda {
14 | URI.open("https://github.com/#{self.class.github_config.name}/archive/#{commit}.tar.gz")
15 | })] + super
16 | end
17 |
18 | def source_url_directory_name
19 | # GitHub strips leading `v` from version tags
20 | commit = version_git_tag&.gsub(/^v/, "") || version_git_commit
21 | "#{self.class.github_config.name.split("/").last}-#{commit}"
22 | end
23 | end
24 |
25 | module ClassMethods
26 | attr_reader :github_config
27 |
28 | def github(name, download_version_tags: true, tag_prefix: /v?/, version_pattern: nil)
29 | @github_config = Config.new(name:, download_version_tags:)
30 | include Pgpm::Package::Git
31 | include Methods
32 | git "https://github.com/#{@github_config.name}", download_version_tags:, tag_prefix:, version_pattern:
33 | end
34 | end
35 |
36 | def self.included(base_class)
37 | base_class.extend(ClassMethods)
38 | end
39 | end
40 | end
41 | end
42 |
--------------------------------------------------------------------------------
/lib/pgpm/package/initialization.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Initialization
6 | def initialize(version)
7 | @version = version
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/pgpm/package/make.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Make
6 | def build_steps
7 | [Pgpm::Commands::Make.new("PG_CONFIG=$PG_CONFIG")] if makefile_present?
8 | end
9 |
10 | def install_steps
11 | return unless makefile_present?
12 |
13 | [Pgpm::Commands::Make.new("install", "DESTDIR=$PGPM_INSTALL_ROOT", "PG_CONFIG=$PG_CONFIG")]
14 | end
15 |
16 | def makefile_present?
17 | !Dir.glob(%w[Makefile GNUmakefile makefile], base: source.to_s).empty?
18 | end
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/lib/pgpm/package/metadata.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Metadata
6 | def summary
7 | "TODO: summary"
8 | end
9 |
10 | def description
11 | "TODO: description"
12 | end
13 |
14 | def all_searchable_texts
15 | [name, summary, description]
16 | end
17 |
18 | def license
19 | "TODO: license"
20 | end
21 |
22 | def release_date; end
23 |
24 | def broken?
25 | requires.any?(&:broken?)
26 | end
27 |
28 | module ClassMethods
29 | def extension_name
30 | self[:latest]&.extension_name
31 | end
32 |
33 | def description
34 | self[:latest]&.description
35 | end
36 |
37 | def summary
38 | self[:latest]&.summary
39 | end
40 |
41 | def license
42 | self[:latest]&.license
43 | end
44 |
45 | def release_date
46 | self[:latest]&.release_date
47 | end
48 |
49 | def all_searchable_texts
50 | self[:latest]&.all_searchable_texts || []
51 | end
52 | end
53 |
54 | def self.included(base_class)
55 | base_class.extend(ClassMethods)
56 | end
57 | end
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/lib/pgpm/package/naming.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Naming
6 | module ClassMethods
7 | def package_name(exclude_namespace: false)
8 | modules = to_s.split("::")
9 | class_name = modules.last
10 | name = @name || Dry::Inflector.new.underscore(class_name)
11 | if exclude_namespace
12 | name
13 | else
14 | namespace = modules[..-2].map { |m| Dry::Inflector.new.underscore(m) }.join("/")
15 | namespace += "/" unless namespace.empty?
16 | namespace + name
17 | end
18 | end
19 |
20 | protected
21 |
22 | def name(name)
23 | @name = name
24 | end
25 | end
26 |
27 | def self.included(base_class)
28 | base_class.extend(ClassMethods)
29 | end
30 |
31 | def name(exclude_namespace: true)
32 | self.class.package_name(exclude_namespace:)
33 | end
34 |
35 | def extension_name
36 | name
37 | end
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/lib/pgpm/package/native.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Native
6 | def native?(path = ".")
7 | Dir.glob("**/*.{c,rs,cpp,cc,zig,go,adb,s}", base: File.join(source, path)).any?
8 | end
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/pgpm/package/packaging.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Packaging
6 | def to_rpm_spec(**opts)
7 | Pgpm::RPM::Spec.new(self, **opts)
8 | end
9 |
10 | def to_deb_spec(**opts)
11 | Pgpm::Deb::Spec.new(self, **opts)
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/pgpm/package/pgxn.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "oj"
4 |
5 | module Pgpm
6 | class Package
7 | module PGXN
8 | def provides_pgxn_meta_json?
9 | File.directory?(source) && File.file?(pgxn_meta_json_path)
10 | end
11 |
12 | def pgxn_meta_json
13 | @pgxn_meta_json ||= Oj.load(File.read(pgxn_meta_json_path))
14 | end
15 |
16 | def pgxn_meta_json_path
17 | source.join("META.json")
18 | end
19 |
20 | def extension_name
21 | if provides_pgxn_meta_json?
22 | pgxn_meta_json["name"]
23 | else
24 | super
25 | end
26 | end
27 |
28 | def summary
29 | if provides_pgxn_meta_json?
30 | pgxn_meta_json["abstract"]
31 | else
32 | super
33 | end
34 | end
35 |
36 | def description
37 | if provides_pgxn_meta_json?
38 | pgxn_meta_json["description"]
39 | else
40 | super
41 | end
42 | end
43 |
44 | def license
45 | if provides_pgxn_meta_json?
46 | lic = pgxn_meta_json["license"]
47 | case lic
48 | when Hash
49 | lic.keys.join(" or ")
50 | when Array
51 | lic.join(" or ")
52 | when String
53 | lic
54 | end
55 | else
56 | super
57 | end
58 | end
59 |
60 | def license_text
61 | path = source.to_s
62 | %w[license lisence unlicense unlisence copying].each do |fn|
63 | [fn, fn.capitalize, fn.upcase].each do |fn2|
64 | ["", ".txt", ".md"].each do |fn3|
65 | if File.exist?("#{path}/#{fn2}#{fn3}")
66 | return File.read("#{path}/#{fn2}#{fn3}")
67 | end
68 | end
69 | end
70 | end
71 | nil
72 | end
73 | end
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/lib/pgpm/package/rust.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "open-uri"
4 | require "perfect_toml"
5 |
6 | module Pgpm
7 | class Package
8 | # rubocop:disable Metrics/ModuleLength
9 | module Rust
10 | ARCH_MAPPING = { "arm64" => "aarch64" }.freeze
11 | OS_MAPPING = { "linux" => "unknown-linux-gnu" }.freeze
12 |
13 | def rust_default_features
14 | []
15 | end
16 |
17 | def sources
18 | if cargo_toml_present?
19 | return @srcs if @srcs
20 |
21 | @srcs = super
22 |
23 | vendor_dir = Dir.mktmpdir("pgpm")
24 |
25 | podman_cmd = "run -v #{Pgpm::Cache.directory}:#{Pgpm::Cache.directory} -v #{vendor_dir}:#{vendor_dir} -i rust"
26 | Podman.run("#{podman_cmd} cargo add --manifest-path #{source}/Cargo.toml --dev cargo-pgrx@#{pgrx_version}")
27 | Podman.run("#{podman_cmd} cargo vendor --versioned-dirs --manifest-path #{source}/Cargo.toml #{vendor_dir}/vendor")
28 | vendored_pgrx_version = Dir.glob("cargo-pgrx-*", base: File.join(vendor_dir, "vendor"))[0].split("-").last
29 | # Get cargo-pgrx's dependencies vendored, too
30 | Podman.run("#{podman_cmd} cargo vendor --no-delete --versioned-dirs --manifest-path #{vendor_dir}/vendor/cargo-pgrx-#{vendored_pgrx_version}/Cargo.toml #{vendor_dir}/vendor")
31 | File.write(File.join(vendor_dir, "vendor", "PGRX_VERSION"), vendored_pgrx_version) # Write it down so that configure steps don't have to guess
32 |
33 | @srcs.push(vendored_tar_gz(vendor_dir))
34 |
35 | FileUtils.rm_rf(vendor_dir)
36 |
37 | @srcs.push(Pgpm::OnDemandFile.new("rust.tar.xz", lambda {
38 | # rubocop:disable Security/Open
39 | URI.open(channel_rust_stable[:pkg][:rust][:target][rust_target.to_sym][:xz_url])
40 | # rubocop:enable Security/Open
41 | }))
42 |
43 | @srcs
44 | else
45 | super
46 | end
47 | end
48 |
49 | def build_dependencies
50 | if cargo_toml_present?
51 | super + [
52 | # I currently have no hope of being able to get distros to support bleeding-edge MSRV,
53 | # so this is what we mean but for now we just package Rust with us (which makes our sources
54 | # large, sadly)
55 | # "cargo >= #{rust_minimum_version}", "rust >= #{rust_minimum_version}",
56 | # "rustfmt >= #{rust_minimum_version}", # pgrx->bindgen
57 | "openssl-devel" # pgrx needs it
58 | ]
59 | else
60 | super
61 | end
62 | end
63 |
64 | def configure_steps
65 | if cargo_toml_present?
66 | config = <<~EOF
67 | [profile.release-with-debug]
68 | inherits = "release"
69 | debug = true
70 |
71 | [source.crates-io]
72 | replace-with = "vendored-sources"
73 |
74 | [source.vendored-sources]
75 | directory = "vendor"
76 | EOF
77 | super + [
78 | "rust-#{current_stable_rust}-#{rust_target}/install.sh --prefix=rust",
79 | "export PATH=$(pwd)/rust/bin:$PATH",
80 | "mkdir -p .cargo && echo '#{config}' >> .cargo/config.toml", "cargo install --path vendor/cargo-pgrx-$(cat vendor/PGRX_VERSION)", "cargo pgrx init --pg#{Pgpm::Postgres::Distribution.in_scope.major_version} $PG_CONFIG", "cargo generate-lockfile --offline"
81 | ]
82 | else
83 | super
84 | end
85 | end
86 |
87 | def build_steps
88 | features = ["pg#{Pgpm::Postgres::Distribution.in_scope.major_version}"] + rust_default_features
89 | if cargo_toml_present?
90 | super + [
91 | "export PATH=$(pwd)/rust/bin:$PATH",
92 | "cargo build --profile release-with-debug --no-default-features --features #{features.join(",")}"
93 | ]
94 | else
95 | super
96 | end
97 | end
98 |
99 | def install_steps
100 | if cargo_toml_present?
101 | super + [
102 | "export PATH=$(pwd)/rust/bin:$PATH",
103 | "PGPM_REDIRECT_TO_BUILDROOT=1 cargo pgrx install --profile release-with-debug --pg-config $(pwd)/pg_config.sh"
104 | ]
105 | else
106 | super
107 | end
108 | end
109 |
110 | private
111 |
112 | def rust_target
113 | arch = Pgpm::Arch.in_scope.name
114 | os = Pgpm::OS.in_scope.kind
115 | "#{ARCH_MAPPING[arch] || arch}-#{OS_MAPPING[os] || os}"
116 | end
117 |
118 | def cargo_toml_present?
119 | File.exist?(File.join(source, "Cargo.toml"))
120 | end
121 |
122 | def cargo_toml
123 | @cargo_toml ||= PerfectTOML.load_file(File.join(source, "Cargo.toml"), symbolize_names: true)
124 | end
125 |
126 | def pgrx_version
127 | cargo_toml[:dependencies][:pgrx]
128 | end
129 |
130 | def rust_minimum_version
131 | # pgrx has no MSRV policy, always requiring the latest
132 | current_stable_rust
133 | end
134 |
135 | def channel_rust_stable
136 | @@channel_rust_stable ||= PerfectTOML.load_file(URI.open("https://static.rust-lang.org/dist/channel-rust-stable.toml"), symbolize_names: true)
137 | end
138 |
139 | def current_stable_rust
140 | channel_rust_stable[:pkg][:rust][:version].split(" ").first
141 | end
142 |
143 | def vendored_tar_gz(dir)
144 | s = String.new
145 | begin
146 | sgz = Zlib::GzipWriter.new(StringIO.new(s))
147 | tar = Minitar::Output.open(sgz)
148 | Find.find(dir) do |entry|
149 | stat = File.stat(entry)
150 | data = File.directory?(entry) ? nil : File.binread(entry)
151 | info = { name: Pathname(entry).relative_path_from(dir).to_s,
152 | mode: stat.mode, uid: stat.uid, gid: stat.gid, mtime: stat.mtime }
153 | Minitar.pack_as_file(info, data, tar)
154 | end
155 | ensure
156 | # Closes both tar and sgz.
157 | tar.close
158 | end
159 | Pgpm::OnDemandFile.new("vendored-sources.tar.gz", -> { StringIO.open(s) })
160 | end
161 |
162 | # rubocop:enable Metrics/ModuleLength
163 | end
164 | end
165 | end
166 |
--------------------------------------------------------------------------------
/lib/pgpm/package/source.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Source
6 | def source
7 | raise StandardError, "no source specified"
8 | end
9 |
10 | def sources
11 | []
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/pgpm/package/subscripting.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "semver_dialects"
4 |
5 | module Pgpm
6 | class Package
7 | module Subscripting
8 | module ClassMethods
9 | def [](name)
10 | if self == Pgpm::Package
11 | all_subclasses.find { |klass| klass.package_name == name }
12 | elsif name == :latest && package_versioning_scheme == :semver
13 | return nil if package_versions.empty?
14 |
15 | version = package_versions.map { |ver| ver.is_a?(Pgpm::Package::Version) ? ver : Pgpm::Package::Version.new(ver) }.max
16 | new(Pgpm::Package::Version.new(version.to_s))
17 | elsif name == :latest
18 | null
19 | elsif package_versions.include?(name)
20 | new(Pgpm::Package::Version.new(name.to_s))
21 | else
22 | all_subclasses.find { |klass| klass.package_name == name }
23 | end
24 | end
25 | end
26 |
27 | def self.included(base_class)
28 | base_class.extend(ClassMethods)
29 | end
30 | end
31 | end
32 | end
33 |
--------------------------------------------------------------------------------
/lib/pgpm/package/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "semver_dialects"
4 |
5 | module Pgpm
6 | class Package
7 | class Version
8 | include Comparable
9 |
10 | def initialize(version)
11 | recognize_version(version)
12 | @version_string = version.to_s
13 | end
14 |
15 | def to_s
16 | @version_string
17 | end
18 |
19 | def ==(other)
20 | to_s == other.to_s
21 | end
22 |
23 | alias eql? ==
24 |
25 | def <=>(other)
26 | raise "unsupported version provider" unless @version.is_a?(SemverDialects::BaseVersion)
27 |
28 | @version <=> SemverDialects.parse_version(@semver_type, other.to_s)
29 | end
30 |
31 | def hash
32 | to_s.hash
33 | end
34 |
35 | def major
36 | to_s.split(".").first.to_i
37 | end
38 |
39 | def minor
40 | to_s.split(".")[1].to_i
41 | end
42 |
43 | def satisfies?(range)
44 | raise "unsupported version provider" unless @version.is_a?(SemverDialects::BaseVersion)
45 |
46 | SemverDialects.version_satisfies?(@semver_type, @version_string, range)
47 | end
48 |
49 | private
50 |
51 | def recognize_version(version)
52 | @semver_type, @version = %w[cargo deb rpm].lazy.filter_map do |type|
53 | [type, SemverDialects.parse_version(type, version)]
54 | rescue SemverDialects::InvalidVersionError
55 | nil
56 | end.first || version
57 | end
58 | end
59 | end
60 | end
61 |
--------------------------------------------------------------------------------
/lib/pgpm/package/versioning.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | class Package
5 | module Versioning
6 | module ClassMethods
7 | def package_versions
8 | warn("No versions defined for #{package_name}")
9 | []
10 | end
11 |
12 | def package_versioning_scheme
13 | @package_versioning_scheme ||= :semver
14 | end
15 |
16 | def versioning_scheme(scheme)
17 | @package_versioning_scheme = scheme
18 | end
19 | end
20 |
21 | def self.included(base_class)
22 | base_class.extend(ClassMethods)
23 | end
24 |
25 | attr_reader :version
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/pgpm/package/with_path.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "minitar"
4 | require "find"
5 | require "zlib"
6 |
7 | module Pgpm
8 | class Package
9 | module WithPath
10 | def with_path(path)
11 | @with_path = File.absolute_path(path)
12 | self
13 | end
14 |
15 | def source_url_directory_name
16 | if @with_path
17 | File.basename(@with_path)
18 | else
19 | super
20 | end
21 | end
22 |
23 | def source
24 | if @with_path
25 | Pathname(@with_path)
26 | else
27 | super
28 | end
29 | end
30 |
31 | def sources
32 | if @with_path
33 | [source_tar_gz]
34 | else
35 | super
36 | end
37 | end
38 |
39 | private
40 |
41 | def source_tar_gz
42 | Pgpm::OnDemandFile.new("sources.tar.gz", lambda {
43 | s = String.new
44 | begin
45 | dir = source
46 | sgz = Zlib::GzipWriter.new(StringIO.new(s))
47 | tar = Minitar::Output.open(sgz)
48 | Find.find(dir) do |entry|
49 | stat = File.stat(entry)
50 | data = File.directory?(entry) ? nil : File.binread(entry)
51 | info = { name: Pathname(entry).relative_path_from(File.dirname(source)).to_s,
52 | mode: stat.mode, uid: stat.uid, gid: stat.gid, mtime: stat.mtime }
53 | Minitar.pack_as_file(info, data, tar)
54 | end
55 | ensure
56 | # Closes both tar and sgz.
57 | tar.close
58 | end
59 | StringIO.open(s)
60 | })
61 | end
62 | end
63 | end
64 | end
65 |
--------------------------------------------------------------------------------
/lib/pgpm/podman.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "English"
4 | require "open3"
5 | require "tty-command"
6 |
7 | module Pgpm
8 | module Podman
9 | def self.run(command, unhandled_reboot_mitigation: true, print_stdout: true)
10 | result = TTY::Command.new(printer: :null).run("podman #{command}", pty: true) do |out, err|
11 | $stderr.print(out) if print_stdout
12 | warn err if err
13 | end
14 |
15 | result.out
16 | rescue TTY::Command::ExitError => e
17 | if unhandled_reboot_mitigation && e.message =~ /Please delete/
18 | FileUtils.rm_rf(["/run/containers/storage", "/run/libpod"])
19 | return run(command, print_stdout:, unhandled_reboot_mitigation: false)
20 | end
21 |
22 | raise
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/lib/pgpm/postgres/distribution.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "open-uri"
4 | require "nokogiri"
5 | require "lspace"
6 |
7 | module Pgpm
8 | module Postgres
9 | class Distribution
10 | attr_reader :version
11 |
12 | def initialize(postgres_version)
13 | @version = postgres_version
14 | end
15 |
16 | def build_time_requirement_packages
17 | raise NotImplementedError
18 | end
19 |
20 | def major_version
21 | @version.split(".").first.to_i
22 | end
23 |
24 | def minor_version
25 | @version.split(".")[1].to_i
26 | end
27 |
28 | def with_scope(&block)
29 | LSpace.with(pgpm_target_postgres: self) do
30 | block.yield
31 | end
32 | end
33 |
34 | def self.in_scope
35 | LSpace[:pgpm_target_postgres]
36 | end
37 |
38 | def self.versions
39 | return @versions if @versions
40 |
41 | versions_rss = Nokogiri::XML(URI.open("https://www.postgresql.org/versions.rss"))
42 | @versions = versions_rss.search("description").map do |ver|
43 | maj, min = ver.content.split(" ").first.split(".")
44 | if "#{maj}.#{min}" =~ /\d+\.\d+/
45 | Pgpm::Package::Version.new("#{maj}.#{min}")
46 | end
47 | end.compact.sort.reverse.group_by(&:major).map do |(major, group)|
48 | minor_versions = group.map(&:minor)
49 | full_minor_range = (0..minor_versions.max)
50 | missing_minors = full_minor_range.to_a - minor_versions
51 | filled_versions = []
52 | missing_minors.each do |minor|
53 | filled_versions << Pgpm::Package::Version.new("#{major}.#{minor}")
54 | end
55 |
56 | filled_versions.concat(group).reverse
57 | end.flatten.reverse
58 | end
59 | end
60 | end
61 | end
62 |
--------------------------------------------------------------------------------
/lib/pgpm/postgres/redhat_based_pgdg.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module Postgres
5 | class RedhatBasedPgdg < Distribution
6 | def build_time_requirement_packages
7 | ["postgresql#{major_version} = #{version}",
8 | "postgresql#{major_version}-devel = #{version}",
9 | "postgresql#{major_version}-server = #{version}"]
10 | end
11 |
12 | def requirement_packages
13 | ["postgresql#{major_version} = #{version}"]
14 | end
15 |
16 | def pg_config_package
17 | "postgresql#{major_version}"
18 | end
19 |
20 | def package_for(extension)
21 | case extension
22 | when Contrib::Plpython3u
23 | "postgresql#{major_version}-plpython3 = #{version}"
24 | else
25 | "postgresql#{major_version}-contrib = #{version}"
26 | end
27 | end
28 | end
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "digest"
4 | require "open-uri"
5 |
6 | module Pgpm
7 | module RPM
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/builder.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module RPM
5 | class Builder
6 | def initialize(spec)
7 | @spec = spec
8 | end
9 |
10 | def source_builder(target_directory = nil)
11 | target_directory ||= "."
12 | dir = Dir.mktmpdir("pgpm")
13 | File.open(Pathname(dir).join("#{safe_package_name}.spec"), "w") do |specfile|
14 | specfile.write(@spec.to_s)
15 | specfile.close
16 | sources = File.join(dir, "sources")
17 | FileUtils.mkdir_p(sources)
18 | @spec.sources.map do |src|
19 | print "Downloading #{src.name}..."
20 | srcfile = File.join(sources, src.name)
21 | File.write(srcfile, src.read)
22 | puts " done."
23 | end
24 | cfg = Pgpm::RPM::Mock::Config.new(Pgpm::OS.in_scope.mock_config)
25 | Pgpm::RPM::Mock::Operation.buildsrpm(specfile.path, sources, config: cfg.path, result_dir: target_directory, cb: lambda {
26 | FileUtils.rm_rf(dir)
27 | })
28 | end
29 | end
30 |
31 | def versionless_builder(target_directory = nil)
32 | target_directory ||= "."
33 | dir = Dir.mktmpdir("pgpm")
34 | File.open(Pathname(dir).join("#{safe_package_name}.spec"), "w") do |specfile|
35 | specfile.write(@spec.versionless)
36 | specfile.close
37 | cfg = Pgpm::RPM::Mock::Config.new(Pgpm::OS.in_scope.mock_config)
38 | Pgpm::RPM::Mock::Operation.buildsrpm(specfile.path, nil, config: cfg.path, result_dir: target_directory, cb: lambda {
39 | FileUtils.rm_rf(dir)
40 | })
41 | end
42 | end
43 |
44 | def self.builder(srpm)
45 | target_directory ||= "."
46 | cfg = Pgpm::RPM::Mock::Config.new(Pgpm::OS.in_scope.mock_config)
47 | srpm = [srpm] if srpm.is_a?(String)
48 | srpm.reduce(nil) do |b, rpm|
49 | op = Pgpm::RPM::Mock::Operation.rebuild(rpm, config: cfg.path, result_dir: target_directory)
50 | b.nil? ? op : b.chain(op)
51 | end
52 | end
53 |
54 | private
55 |
56 | def safe_package_name
57 | @spec.package.name.gsub(%r{/}, "__")
58 | end
59 | end
60 | end
61 | end
62 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/mock/config.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module RPM
5 | module Mock
6 | class Config
7 | def initialize(name)
8 | @source = name
9 | @path = File.absolute_path(File.join(File.dirname(__FILE__), "..", "mock", "configs", "#{name}.cfg"))
10 | end
11 |
12 | attr_reader :path
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/mock/configs/rocky+epel-9-aarch64+pgdg.cfg:
--------------------------------------------------------------------------------
1 | include('rocky+epel-9-aarch64.cfg')
2 |
3 | config_opts['root'] = 'rocky+epel-9-aarch64+pgdg{{pgdg_version}}'
4 |
5 | config_opts['description'] = 'Rocky Linux EPEL 9 with pgdg {{ pgdg_version }}'
6 | config_opts['dnf.conf'] += """
7 |
8 | #########################################################
9 | # PGDG Red Hat Enterprise Linux / Rocky repositories #
10 | #########################################################
11 |
12 | # PGDG Red Hat Enterprise Linux / Rocky stable common repository for all PostgreSQL versions
13 |
14 | [pgdg-common]
15 | name=PostgreSQL common RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
16 | baseurl=https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-$releasever-{{target_arch}}
17 | enabled=1
18 | gpgcheck=1
19 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
20 | repo_gpgcheck = 1
21 |
22 | # Red Hat recently breaks compatibility between 9.n and 9.n+1. PGDG repo is
23 | # affected with the LLVM repo. This is a band aid repo for the llvmjit users
24 | # whose installations cannot be updated.
25 |
26 | [pgdg-rocky9-sysupdates]
27 | name=PostgreSQL Supplementary ucommon RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
28 | baseurl=https://download.postgresql.org/pub/repos/yum/common/pgdg-rocky9-sysupdates/redhat/rhel-$releasever-{{target_arch}}
29 | enabled=0
30 | gpgcheck=1
31 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
32 | repo_gpgcheck = 1
33 |
34 | # We provide extra package to support some RPMs in the PostgreSQL RPM repo, like
35 | # consul, haproxy, etc.
36 |
37 | [pgdg-rhel9-extras]
38 | name=Extra packages to support some RPMs in the PostgreSQL RPM repo for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
39 | baseurl=https://download.postgresql.org/pub/repos/yum/common/pgdg-rhel$releasever-extras/redhat/rhel-$releasever-{{target_arch}}
40 | enabled=0
41 | gpgcheck=1
42 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
43 | repo_gpgcheck = 1
44 |
45 | # PGDG Red Hat Enterprise Linux / Rocky stable repositories:
46 |
47 | [pgdg{{pgdg_version}}]
48 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
49 | baseurl=https://download.postgresql.org/pub/repos/yum/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
50 | enabled=1
51 | gpgcheck=1
52 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
53 | repo_gpgcheck = 1
54 |
55 | # PGDG RHEL / Rocky / AlmaLinux Updates Testing common repositories.
56 |
57 | [pgdg-common-testing]
58 | name=PostgreSQL common testing RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
59 | baseurl=https://download.postgresql.org/pub/repos/yum/testing/common/redhat/rhel-$releasever-{{target_arch}}
60 | enabled=0
61 | gpgcheck=1
62 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
63 | repo_gpgcheck = 1
64 |
65 | # PGDG RHEL / Rocky / AlmaLinux Updates Testing repositories. (These packages should not be used in production)
66 | # Available for 12 and above.
67 |
68 | [pgdg{{pgdg_version}}-updates-testing]
69 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Updates testing
70 | baseurl=https://download.postgresql.org/pub/repos/yum/testing/17/redhat/rhel-$releasever-{{target_arch}}
71 | enabled=0
72 | gpgcheck=0
73 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
74 | repo_gpgcheck = 1
75 |
76 | # PGDG Red Hat Enterprise Linux / Rocky SRPM testing common repository
77 |
78 | [pgdg-source-common]
79 | name=PostgreSQL for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source
80 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/common/redhat/rhel-$releasever-{{target_arch}}
81 | enabled=0
82 | gpgcheck=1
83 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
84 | repo_gpgcheck = 1
85 |
86 | # PGDG RHEL / Rocky / AlmaLinux testing common SRPM repository for all PostgreSQL versions
87 |
88 | [pgdg-common-srpm-testing]
89 | name=PostgreSQL common testing SRPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
90 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/testing/common/redhat/rhel-$releasever-{{target_arch}}
91 | enabled=0
92 | gpgcheck=1
93 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
94 | repo_gpgcheck = 1
95 |
96 | # PGDG Source RPMs (SRPM), and their testing repositories:
97 |
98 | [pgdg{{pgdg_version}}-source-updates-testing]
99 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source updates testing
100 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/testing/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
101 | enabled=0
102 | gpgcheck=0
103 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
104 | repo_gpgcheck = 1
105 |
106 | [pgdg{{pgdg_version}}-source]
107 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source
108 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/16/redhat/rhel-$releasever-{{target_arch}}
109 | enabled=0
110 | gpgcheck=1
111 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
112 | repo_gpgcheck = 1
113 |
114 | # Debuginfo/debugsource packages for stable repos
115 |
116 | [pgdg{{pgdg_version}}-debuginfo]
117 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Debuginfo
118 | baseurl=https://dnf-debuginfo.postgresql.org/debug/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
119 | enabled=0
120 | gpgcheck=1
121 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
122 | repo_gpgcheck = 1
123 |
124 | [pgdg{{pgdg_version}}-updates-testing-debuginfo]
125 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Debuginfo
126 | baseurl=https://dnf-debuginfo.postgresql.org/testing/debug/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
127 | enabled=0
128 | gpgcheck=0
129 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-AARCH64-RHEL
130 | repo_gpgcheck = 1
131 | """
--------------------------------------------------------------------------------
/lib/pgpm/rpm/mock/configs/rocky+epel-9-x86_64+pgdg.cfg:
--------------------------------------------------------------------------------
1 | include('rocky+epel-9-x86_64.cfg')
2 |
3 | config_opts['root'] = 'rocky+epel-9-x86_64+pgdg{{pgdg_version}}'
4 |
5 | config_opts['description'] = 'Rocky Linux EPEL 9 with pgdg {{ pgdg_version }}'
6 | config_opts['dnf.conf'] += """
7 |
8 | #########################################################
9 | # PGDG Red Hat Enterprise Linux / Rocky repositories #
10 | #########################################################
11 |
12 | # PGDG Red Hat Enterprise Linux / Rocky stable common repository for all PostgreSQL versions
13 |
14 | [pgdg-common]
15 | name=PostgreSQL common RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
16 | baseurl=https://download.postgresql.org/pub/repos/yum/common/redhat/rhel-$releasever-{{target_arch}}
17 | enabled=1
18 | gpgcheck=1
19 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
20 | repo_gpgcheck = 1
21 |
22 | # Red Hat recently breaks compatibility between 9.n and 9.n+1. PGDG repo is
23 | # affected with the LLVM repo. This is a band aid repo for the llvmjit users
24 | # whose installations cannot be updated.
25 |
26 | [pgdg-rocky9-sysupdates]
27 | name=PostgreSQL Supplementary ucommon RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
28 | baseurl=https://download.postgresql.org/pub/repos/yum/common/pgdg-rocky9-sysupdates/redhat/rhel-$releasever-{{target_arch}}
29 | enabled=0
30 | gpgcheck=1
31 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
32 | repo_gpgcheck = 1
33 |
34 | # We provide extra package to support some RPMs in the PostgreSQL RPM repo, like
35 | # consul, haproxy, etc.
36 |
37 | [pgdg-rhel9-extras]
38 | name=Extra packages to support some RPMs in the PostgreSQL RPM repo for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
39 | baseurl=https://download.postgresql.org/pub/repos/yum/common/pgdg-rhel$releasever-extras/redhat/rhel-$releasever-{{target_arch}}
40 | enabled=0
41 | gpgcheck=1
42 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
43 | repo_gpgcheck = 1
44 |
45 | # PGDG Red Hat Enterprise Linux / Rocky stable repositories:
46 |
47 | [pgdg{{pgdg_version}}]
48 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
49 | baseurl=https://download.postgresql.org/pub/repos/yum/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
50 | enabled=1
51 | gpgcheck=1
52 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
53 | repo_gpgcheck = 1
54 |
55 | # PGDG RHEL / Rocky / AlmaLinux Updates Testing common repositories.
56 |
57 | [pgdg-common-testing]
58 | name=PostgreSQL common testing RPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
59 | baseurl=https://download.postgresql.org/pub/repos/yum/testing/common/redhat/rhel-$releasever-{{target_arch}}
60 | enabled=0
61 | gpgcheck=1
62 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
63 | repo_gpgcheck = 1
64 |
65 | # PGDG RHEL / Rocky / AlmaLinux Updates Testing repositories. (These packages should not be used in production)
66 | # Available for 12 and above.
67 |
68 | [pgdg{{pgdg_version}}-updates-testing]
69 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Updates testing
70 | baseurl=https://download.postgresql.org/pub/repos/yum/testing/17/redhat/rhel-$releasever-{{target_arch}}
71 | enabled=0
72 | gpgcheck=0
73 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
74 | repo_gpgcheck = 1
75 |
76 | # PGDG Red Hat Enterprise Linux / Rocky SRPM testing common repository
77 |
78 | [pgdg-source-common]
79 | name=PostgreSQL for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source
80 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/common/redhat/rhel-$releasever-{{target_arch}}
81 | enabled=0
82 | gpgcheck=1
83 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
84 | repo_gpgcheck = 1
85 |
86 | # PGDG RHEL / Rocky / AlmaLinux testing common SRPM repository for all PostgreSQL versions
87 |
88 | [pgdg-common-srpm-testing]
89 | name=PostgreSQL common testing SRPMs for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}}
90 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/testing/common/redhat/rhel-$releasever-{{target_arch}}
91 | enabled=0
92 | gpgcheck=1
93 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
94 | repo_gpgcheck = 1
95 |
96 | # PGDG Source RPMs (SRPM), and their testing repositories:
97 |
98 | [pgdg{{pgdg_version}}-source-updates-testing]
99 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source updates testing
100 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/testing/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
101 | enabled=0
102 | gpgcheck=0
103 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
104 | repo_gpgcheck = 1
105 |
106 | [pgdg{{pgdg_version}}-source]
107 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Source
108 | baseurl=https://download.postgresql.org/pub/repos/yum/srpms/16/redhat/rhel-$releasever-{{target_arch}}
109 | enabled=0
110 | gpgcheck=1
111 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
112 | repo_gpgcheck = 1
113 |
114 | # Debuginfo/debugsource packages for stable repos
115 |
116 | [pgdg{{pgdg_version}}-debuginfo]
117 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Debuginfo
118 | baseurl=https://dnf-debuginfo.postgresql.org/debug/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
119 | enabled=0
120 | gpgcheck=1
121 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
122 | repo_gpgcheck = 1
123 |
124 | [pgdg{{pgdg_version}}-updates-testing-debuginfo]
125 | name=PostgreSQL {{pgdg_version}} for RHEL / Rocky / AlmaLinux $releasever - {{target_arch}} - Debuginfo
126 | baseurl=https://dnf-debuginfo.postgresql.org/testing/debug/{{pgdg_version}}/redhat/rhel-$releasever-{{target_arch}}
127 | enabled=0
128 | gpgcheck=0
129 | gpgkey=https://download.postgresql.org/pub/repos/yum/keys/PGDG-RPM-GPG-KEY-RHEL
130 | repo_gpgcheck = 1
131 | """
--------------------------------------------------------------------------------
/lib/pgpm/rpm/mock/operation.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | module RPM
5 | module Mock
6 | class Operation
7 | def self.buildsrpm(spec, sources, config: nil, result_dir: nil, cb: nil)
8 | buffer_result_dir = Dir.mktmpdir("pgpm")
9 | args = [
10 | "--buildsrpm", "--spec", spec, "--resultdir",
11 | buffer_result_dir
12 | ]
13 | args.push("--sources", sources) if sources
14 | args.push("-r", config.to_s) unless config.nil?
15 | paths = [buffer_result_dir]
16 | paths.push(File.dirname(spec))
17 | paths.push(File.dirname(sources)) if sources
18 | new(*args, paths:, cb: lambda {
19 | rpms = Dir.glob("*.rpm", base: buffer_result_dir).map do |f|
20 | FileUtils.cp(Pathname(buffer_result_dir).join(f), result_dir) unless result_dir.nil?
21 | File.join(File.absolute_path(result_dir), f)
22 | end
23 | FileUtils.rm_rf(buffer_result_dir)
24 | cb.call unless cb.nil?
25 | rpms
26 | })
27 | end
28 |
29 | def self.rebuild(srpm, config: nil, result_dir: nil, cb: nil)
30 | buffer_result_dir = Dir.mktmpdir("pgpm")
31 | args = [
32 | "--rebuild", "--chain", "--recurse", srpm, "--localrepo", buffer_result_dir
33 | ]
34 | args.push("-r", config.to_s) unless config.nil?
35 | paths = [buffer_result_dir]
36 | paths.push(File.dirname(srpm))
37 | new(*args, paths:, cb: lambda {
38 | # Here we glob for **/*.rpm as ``--localrepo` behaves differently from
39 | # `--resultdir`
40 | rpms = Dir.glob("**/*.rpm", base: buffer_result_dir).map do |f|
41 | FileUtils.cp(Pathname(buffer_result_dir).join(f), result_dir) unless result_dir.nil?
42 | File.join(File.absolute_path(result_dir), f)
43 | end
44 | FileUtils.rm_rf(buffer_result_dir)
45 | cb.call unless cb.nil?
46 | rpms
47 | })
48 | end
49 |
50 | def initialize(*args, opts: nil, paths: [], cb: nil)
51 | @args = args
52 | @cb = cb
53 | @paths = paths
54 | @opts = opts || { "print_main_output" => "True", "pgdg_version" => Postgres::Distribution.in_scope.major_version }
55 | end
56 |
57 | attr_reader :args, :cb
58 |
59 | def call
60 | options = @opts.flat_map { |(k, v)| ["--config-opts", "#{k}=#{v}"] }.compact.join(" ")
61 | command = "mock #{options} #{@args.join(" ")}"
62 | map_paths = @paths.map { |p| "-v #{p}:#{p}" }.join(" ")
63 | raise "Failed to execute `#{command}`" unless Podman.run("run -v #{Dir.pwd}:#{Dir.pwd} #{map_paths} --privileged -i ghcr.io/postgres-pm/pgpm #{command}")
64 |
65 | @cb&.call
66 | end
67 |
68 | def chain(op)
69 | raise ArgumentError, "can't chain non-rebuild operations" unless op.args.include?("--rebuild") && @args.include?("--rebuild")
70 |
71 | args.insert(args.index("--localrepo"), *op.args[op.args.index("--recurse") + 1..op.args.index("--localrepo") - 1])
72 | self
73 | end
74 |
75 | def and_then(op)
76 | lambda do
77 | res1 = call
78 | res2 = op.call
79 | if res1.is_a?(Array) && res2.is_a?(Array)
80 | res1 + res2
81 | else
82 | [res1, res2]
83 | end
84 | end
85 | end
86 | end
87 | end
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/scripts/pg_config.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | # Ensure PG_CONFIG is set
4 | if [[ -z "$PG_CONFIG" ]]; then
5 | echo "Error: PG_CONFIG is not set."
6 | exit 1
7 | fi
8 |
9 | # Wrapper function for pg_config
10 | pg_config_wrapper() {
11 | "$PG_CONFIG" "$@" | while read -r line; do
12 | if [[ -n "$PGPM_REDIRECT_TO_BUILDROOT" && -f "$line" || -d "$line" ]]; then
13 | echo "$PGPM_INSTALL_ROOT$line"
14 | else
15 | echo "$line"
16 | fi
17 | done
18 | }
19 |
20 | # Call the wrapper function with the arguments passed to the script
21 | pg_config_wrapper "$@"
22 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/scripts/prepare_artifacts.sh:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env bash
2 |
3 | set -xe
4 |
5 | new_extension_so=
6 |
7 | for file in $(find $PGPM_INSTALL_ROOT -name '*.so'); do
8 | filename=$(basename "$file")
9 | if [[ "$filename" == "${PGPM_EXTENSION_NAME}.so" ]]; then
10 | extension_so=$filename
11 | dir=$(dirname "$file")
12 | extension_dirname=${dir#"$PGPM_INSTALL_ROOT"}
13 | new_extension_so=$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.so
14 | fi
15 | done
16 |
17 | extdir=$PGPM_INSTALL_ROOT$($PG_CONFIG --sharedir)/extension
18 |
19 | # control files
20 | default_control=$extdir/$PGPM_EXTENSION_NAME.control
21 | versioned_control=$extdir/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION.control
22 | controls=("$default_control" "$versioned_control")
23 |
24 |
25 | if [[ -n "$new_extension_so" ]]; then
26 |
27 | mv "$PGPM_INSTALL_ROOT$extension_dirname/$extension_so" "$PGPM_INSTALL_ROOT$extension_dirname/$new_extension_so"
28 |
29 | # Change the extension name in controls
30 | for control in "${controls[@]}"; do
31 | if [[ -f "$control" ]]; then
32 | # extension.so
33 | sed -i "s|${extension_so}'|${new_extension_so}'|g" "$control"
34 | # extension
35 | sed -i "s|${extension_so%".so"}'|${new_extension_so%".so"}'|g" "$control"
36 | fi
37 | done
38 |
39 | # sql files
40 | for sql_file in $(find $PGPM_INSTALL_ROOT -name '*.sql' -type f); do
41 | # extension.so
42 | sed -i "s|/${extension_so}'|/${new_extension_so}'|g" "$sql_file"
43 | # extension
44 | sed -i "s|/${extension_so%".so"}'|/${new_extension_so}'|g" "$sql_file"
45 | done
46 |
47 | # bitcode
48 |
49 | pkglibdir=$PGPM_INSTALL_ROOT$($PG_CONFIG --pkglibdir)
50 |
51 | bitcode_extension=$pkglibdir/bitcode/${extension_so%".so"}
52 | bitcode_index=$pkglibdir/bitcode/${extension_so%".so"}.index.bc
53 |
54 | if [[ -d "${bitcode_extension}" ]]; then
55 | mv "${bitcode_extension}" "$pkglibdir/bitcode/${new_extension_so%".so"}"
56 | fi
57 |
58 | if [[ -f "${bitcode_index}" ]]; then
59 | mv "${bitcode_index}" "$pkglibdir/bitcode/${new_extension_so%".so"}.index.bc"
60 | fi
61 |
62 | # includes
63 | includedir=$PGPM_INSTALL_ROOT$($PG_CONFIG --includedir-server)
64 |
65 | if [[ -d "${includedir}/extension/$PGPM_EXTENSION_NAME" ]]; then
66 | versioned_dir=${includedir}/extension/$PGPM_EXTENSION_NAME--$PGPM_EXTENSION_VERSION
67 | mkdir -p "$versioned_dir"
68 | mv "${includedir}/extension/$PGPM_EXTENSION_NAME" "$versioned_dir"
69 | fi
70 |
71 | # TODO: share, docs, etc.
72 |
73 | fi
74 |
75 |
76 | # Make sure we don't build a default control as it belongs
77 | # to another package
78 | if [[ -f "$default_control" ]]; then
79 | if [[ -f "$versioned_control" ]]; then
80 | # We don't need default control if versioned is present
81 | rm -f "$default_control"
82 | else
83 | # Default becomes versioned
84 | mv "$default_control" "$versioned_control"
85 | # Don't need default_version
86 | sed -i '/default_version/d' "$versioned_control"
87 | fi
88 | fi
89 |
--------------------------------------------------------------------------------
/lib/pgpm/rpm/spec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "digest"
4 | require "open-uri"
5 |
6 | module Pgpm
7 | module RPM
8 | class Spec
9 | attr_reader :package, :release, :postgres_version, :postgres_distribution
10 |
11 | def initialize(package)
12 | @postgres_distribution = Pgpm::Postgres::Distribution.in_scope
13 | @package = package
14 | @release = 1
15 |
16 | # Needed in order to return correct dependencies for the selected
17 | # version of postgres and selected OS.
18 | @package.postgres_major_version = @postgres_distribution.major_version
19 | end
20 |
21 | def versionless
22 | <<~EOF
23 | Name: pgpm-#{@package.name}-#{@postgres_distribution.version}
24 | Version: #{@package.version}
25 | Release: #{@release}%{?dist}
26 | Summary: #{@package.summary}
27 | License: #{@package.license}
28 |
29 | BuildRequires: #{@postgres_distribution.build_time_requirement_packages.join(" ")}
30 | Requires: pgpm-#{@package.name}+#{@package.version}-#{@postgres_distribution.version}
31 | BuildRequires: pgpm-#{@package.name}+#{@package.version}-#{@postgres_distribution.version}
32 | BuildArch: noarch
33 |
34 | %description
35 | #{@package.description}
36 |
37 | %build
38 |
39 | %install
40 | export PG_CONFIG=$(rpm -ql #{@postgres_distribution.pg_config_package} | grep 'pg_config$')
41 | mkdir -p %{buildroot}$($PG_CONFIG --sharedir)/extension
42 | export CONTROL=%{buildroot}$($PG_CONFIG --sharedir)/extension/#{@package.extension_name}.control
43 | cat $($PG_CONFIG --sharedir)/extension/#{@package.extension_name}--#{@package.version}.control > $CONTROL
44 | echo >> $CONTROL
45 | echo "default_version = '#{@package.version}'" >> $CONTROL
46 | echo ${CONTROL#"%{buildroot}"} > filelist.txt
47 |
48 | %files -f filelist.txt
49 | EOF
50 | end
51 |
52 | def sources
53 | sources = @package.sources.clone
54 | sources.push(Pgpm::OnDemandFile.new("prepare_artifacts.sh", -> { File.open(File.join(File.dirname(__FILE__), "scripts", "prepare_artifacts.sh")) }))
55 | sources.push(Pgpm::OnDemandFile.new("pg_config.sh", -> { File.open(File.join(File.dirname(__FILE__), "scripts", "pg_config.sh")) }))
56 | sources
57 | end
58 |
59 | def to_s
60 | setup_opts = ["-q"]
61 | if @package.source_url_directory_name
62 | setup_opts.push("-n", @package.source_url_directory_name)
63 | else
64 | setup_opts.push("-n", "#{@package.name}-#{@package.version}")
65 | end
66 |
67 | <<~EOF
68 | Name: pgpm-#{@package.name}+#{@package.version}-#{@postgres_distribution.version}
69 | Version: 1
70 | Release: 1%{?dist}
71 | Summary: #{@package.summary}
72 | License: #{@package.license}
73 | #{sources.each_with_index.map { |src, index| "Source#{index}: #{src.name}" }.join("\n")}
74 |
75 | BuildRequires: #{@postgres_distribution.build_time_requirement_packages.join(" ")}
76 | #{@package.build_dependencies.uniq.map { |dep| "BuildRequires: #{dep}" }.join("\n")}
77 | #{@package.dependencies.uniq.map { |dep| "Requires: #{dep}" }.join("\n")}
78 | #{@package.requires.uniq.map do |dep|
79 | req = dep.contrib? ? @postgres_distribution.package_for(dep) : "pgpm-#{dep.name}+#{dep.version}-#{@postgres_distribution.version}"
80 | raise "Can't build with a broken dependency #{dep.name}@#{dep.version}" if dep.broken?
81 |
82 | "Requires: #{req}#{"\nBuildRequires: #{req}" if dep.contrib?}"
83 | end.join("\n")
84 | }
85 | Requires: #{@postgres_distribution.requirement_packages.join(" ")}
86 | #{"BuildArch: noarch" unless @package.native?}
87 |
88 | %description
89 | #{@package.description}
90 |
91 | %prep
92 | %setup #{setup_opts.join(" ")}
93 | #{(sources[1..] || []).filter { |s| unpack?(s) }.each_with_index.map { |_src, index| "%setup -T -D #{setup_opts.join(" ")} -a #{index + 1}" }.join("\n")}
94 |
95 | export PG_CONFIG=$(rpm -ql #{@postgres_distribution.pg_config_package} | grep 'pg_config$')
96 | #{@package.configure_steps.map(&:to_s).join("\n")}
97 |
98 | %build
99 | export PG_CONFIG=$(rpm -ql #{@postgres_distribution.pg_config_package} | grep 'pg_config$')
100 | export PGPM_INSTALL_ROOT=%{buildroot}
101 | #{@package.build_steps.map(&:to_s).join("\n")}
102 |
103 | %install
104 | export PG_CONFIG=$(rpm -ql #{@postgres_distribution.pg_config_package} | grep 'pg_config$')
105 | export PGPM_INSTALL_ROOT=%{buildroot}
106 | cp %{SOURCE#{sources.find_index { |src| src.name == "pg_config.sh" }}} ./pg_config.sh
107 | chmod +x ./pg_config.sh
108 | find %{buildroot} -type f | sort - | sed 's|^%{buildroot}||' > .pgpm_before | sort
109 | #{@package.install_steps.map(&:to_s).join("\n")}
110 | export PGPM_EXTENSION_NAME="#{@package.extension_name}"
111 | export PGPM_EXTENSION_VERSION="#{@package.version}"
112 | cp %{SOURCE#{sources.find_index { |src| src.name == "prepare_artifacts.sh" }}} ./prepare_artifacts.sh
113 | chmod +x ./prepare_artifacts.sh
114 | ./prepare_artifacts.sh
115 | find %{buildroot} -type f | sort - | sed 's|^%{buildroot}||' > .pgpm_after | sort
116 | comm -13 .pgpm_before .pgpm_after | sort -u > filelist.txt
117 |
118 | %files -f filelist.txt
119 |
120 |
121 | %changelog
122 | EOF
123 | end
124 |
125 | private
126 |
127 | def unpack?(src)
128 | src = src.name if src.respond_to?(:name)
129 | src.to_s.end_with?(".tar.gz") || src.to_s.end_with?(".tar.xz")
130 | end
131 | end
132 | end
133 | end
134 |
--------------------------------------------------------------------------------
/lib/pgpm/scoped_object.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "delegate"
4 |
5 | module Pgpm
6 | class ScopedObject < SimpleDelegator
7 | def initialize(obj, *scopes)
8 | @scopes = scopes
9 | super(obj)
10 | end
11 |
12 | def method_missing(method, *args, &block)
13 | __scoped_execution(@scopes.clone, method, *args, &block)
14 | end
15 |
16 | def respond_to_missing?(m, include_private)
17 | __getobj__.respond_to_missing?(m, include_private)
18 | end
19 |
20 | private
21 |
22 | def __scoped_execution(scopes, method, *args, &block)
23 | if scopes.empty?
24 | __getobj__.send(method, *args, &block)
25 | else
26 | scope = scopes.pop
27 | scope.with_scope { __scoped_execution(scopes, method, *args, &block) }
28 | end
29 | end
30 | end
31 | end
32 |
--------------------------------------------------------------------------------
/lib/pgpm/version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Pgpm
4 | VERSION = "0.1.0"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/acl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Acl < Pgpm::Package
4 | github "arkhipov/acl"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/age.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Age < Pgpm::Package
4 | github "apache/age"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/aggs_for_arrays.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AggsForArrays < Pgpm::Package
4 | github "pjungwir/aggs_for_arrays"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/aggs_for_vecs.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AggsForVecs < Pgpm::Package
4 | github "pjungwir/aggs_for_vecs"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/anon.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Anon < Pgpm::Package
4 | git "https://gitlab.com/dalibo/postgresql_anonymizer/"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/arraymath.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Arraymath < Pgpm::Package
4 | github "pramsey/pgsql-arraymath"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/asn1oid.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Asn1oid < Pgpm::Package
4 | github "df7cb/pgsql-asn1oid"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/aws_s3.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class AwsS3 < Pgpm::Package
4 | github "chimpler/postgres-aws-s3"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/base36.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Base36 < Pgpm::Package
4 | github "adjust/pg-base36"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/base62.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Base62 < Pgpm::Package
4 | github "adjust/pg-base62"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/bgw_replstatus.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class BgwReplstatus < Pgpm::Package
4 | github "mhagander/bgw_replstatus"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/chkpass.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Chkpass < Pgpm::Package
4 | github "lacanoid/chkpass"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/citus.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Citus < Pgpm::Package
4 | github "citusdata/citus"
5 |
6 | def build_steps
7 | ["./configure"] + super
8 | end
9 |
10 | def build_dependencies
11 | super + %w[libcurl-devel lz4-devel libzstd-devel openssl-devel krb5-devel]
12 | end
13 |
14 | def dependencies
15 | super + %w[libcurl lz4 libzstd openssl krb5-libs]
16 | end
17 |
18 | def broken?
19 | # https://github.com/citusdata/citus/issues/7708
20 | version < 13 && Pgpm::Postgres::Distribution.in_scope.major_version > 16
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/packages/citus_columnar.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CitusColumnar < Pgpm::Package
4 | github "citusdata/citus"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/columnar.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Columnar < Pgpm::Package
4 | github "hydradatabase/hydra"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/count_distinct.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class CountDistinct < Pgpm::Package
4 | github "tvondra/count_distinct"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/country.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Country < Pgpm::Package
4 | github "adjust/pg-country"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/credcheck.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Credcheck < Pgpm::Package
4 | github "MigOpsRepos/credcheck"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/cryptint.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Cryptint < Pgpm::Package
4 | github "dverite/cryptint"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/currency.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Currency < Pgpm::Package
4 | github "adjust/pg-currency"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/data_historization.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DataHistorization < Pgpm::Package
4 | github "rodo/postgresql-data-historization"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/db2_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Db2Fdw < Pgpm::Package
4 | github "wolfgangbrandl/db2_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/dbt2.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Dbt2 < Pgpm::Package
4 | github "nuodb/dbt2"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/ddl_historization.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DdlHistorization < Pgpm::Package
4 | github "rodo/pg_ddl_historization"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/ddlx.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Ddlx < Pgpm::Package
4 | github "lacanoid/pgddl", tag_prefix: "", version_pattern: /(0|[1-9]\d*)\.(0|[1-9]\d*)/
5 | end
6 |
--------------------------------------------------------------------------------
/packages/ddsketch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Ddsketch < Pgpm::Package
4 | github "tvondra/ddsketch"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/debversion.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Debversion < Pgpm::Package
4 | github "ATIX-AG/postgresql-debversion-evr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/decoder_raw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DecoderRaw < Pgpm::Package
4 | github "michaelpq/pg_plugins"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/decoderbufs.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Decoderbufs < Pgpm::Package
4 | github "debezium/postgres-decoderbufs"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/duckdb_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class DuckdbFdw < Pgpm::Package
4 | github "alitrack/duckdb_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/emaj.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Emaj < Pgpm::Package
4 | github "dalibo/emaj"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/envvar.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Envvar < Pgpm::Package
4 | github "theory/pg-envvar"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/explain_ui.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ExplainUi < Pgpm::Package
4 | github "davidgomes/pg-explain-ui"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/extra_window_functions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class ExtraWindowFunctions < Pgpm::Package
4 | github "xocolatl/extra_window_functions"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/faker.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Faker < Pgpm::Package
4 | github "anpandu/postgresql_faker"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/financial.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Financial < Pgpm::Package
4 | github "intgr/pg_financial"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/firebird_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FirebirdFdw < Pgpm::Package
4 | github "ibarwick/firebird_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/first_last_agg.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class FirstLastAgg < Pgpm::Package
4 | github "wulczer/first_last_agg"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/floatfile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Floatfile < Pgpm::Package
4 | github "pjungwir/floatfile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/floatvec.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Floatvec < Pgpm::Package
4 | github "pjungwir/floatvec"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/geoip.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Geoip < Pgpm::Package
4 | github "tvondra/geoip"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/gzip.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Gzip < Pgpm::Package
4 | github "pramsey/pgsql-gzip"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/h3.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class H3 < Pgpm::Package
4 | github "zachasme/h3-pg"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/h3_postgis.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class H3Postgis < Pgpm::Package
4 | github "zachasme/h3-pg"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hdfs_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HdfsFdw < Pgpm::Package
4 | github "EnterpriseDB/hdfs_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hll.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Hll < Pgpm::Package
4 | github "citusdata/postgresql-hll"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hstore_pllua.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HstorePllua < Pgpm::Package
4 | github "pllua/pllua"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hstore_plluau.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HstorePlluau < Pgpm::Package
4 | github "pllua/pllua"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/http.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Http < Pgpm::Package
4 | github "pramsey/pgsql-http"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_cs_cz.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellCsCz < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_de_de.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellDeDe < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_en_us.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellEnUs < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_fr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellFr < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_ne_np.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellNeNp < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_nl_nl.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellNlNl < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_nn_no.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellNnNo < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_pt_pt.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellPtPt < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_ru_ru.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellRuRu < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hunspell_ru_ru_aot.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class HunspellRuRuAot < Pgpm::Package
4 | github "postgrespro/hunspell_dicts"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/hypopg.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Hypopg < Pgpm::Package
4 | github "HypoPG/hypopg"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/icu_ext.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class IcuExt < Pgpm::Package
4 | github "dverite/icu_ext"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/imgsmlr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Imgsmlr < Pgpm::Package
4 | github "postgrespro/imgsmlr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/index_advisor.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class IndexAdvisor < Pgpm::Package
4 | github "supabase/index_advisor"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/ip4r.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Ip4r < Pgpm::Package
4 | github "RhodiumToad/ip4r"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/jdbc_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class JdbcFdw < Pgpm::Package
4 | github "pgspider/jdbc_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/jsquery.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Jsquery < Pgpm::Package
4 | github "postgrespro/jsquery"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/kafka_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class KafkaFdw < Pgpm::Package
4 | github "adjust/kafka_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/log_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class LogFdw < Pgpm::Package
4 | github "aws/postgresql-logfdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/logerrors.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Logerrors < Pgpm::Package
4 | github "munakoiso/logerrors"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/login_hook.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class LoginHook < Pgpm::Package
4 | github "splendiddata/login_hook"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/lower_quantile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class LowerQuantile < Pgpm::Package
4 | github "tvondra/lower_quantile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/md5hash.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Md5hash < Pgpm::Package
4 | github "tvondra/md5hash"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/meta.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Meta < Pgpm::Package
4 | github "aquameta/meta"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/mimeo.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Mimeo < Pgpm::Package
4 | github "omniti-labs/mimeo"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/mobilitydb.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Mobilitydb < Pgpm::Package
4 | github "MobilityDB/MobilityDB"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/mongo_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MongoFdw < Pgpm::Package
4 | github "EnterpriseDB/mongo_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/multicorn.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Multicorn < Pgpm::Package
4 | github "pgsql-io/multicorn2"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/mysql_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class MysqlFdw < Pgpm::Package
4 | github "EnterpriseDB/mysql_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/noset.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Noset < Pgpm::Package
4 | git "https://gitlab.com/ongresinc/extensions/noset"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/numeral.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Numeral < Pgpm::Package
4 | github "df7cb/postgresql-numeral"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/odbc_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class OdbcFdw < Pgpm::Package
4 | github "CartoDB/odbc_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/ogr_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class OgrFdw < Pgpm::Package
4 | github "pramsey/pgsql-ogr-fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/omnigres/extension_discovery.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "git"
4 | require "parallel"
5 |
6 | module Omnigres
7 | class ExtensionDiscovery
8 | @@extensions = {}
9 | @@git_revisions = {}
10 | @mutex = Mutex.new
11 |
12 | class << self
13 | attr_reader :mutex # Expose a class-level reader for the mutex
14 | end
15 |
16 | def initialize(revision: nil, path: nil)
17 | return if @@extensions[revision]
18 |
19 | suffix = revision ? "-#{revision}" : nil
20 | path ||= Pgpm::Cache.directory.join("omnigres#{suffix}")
21 | self.class.mutex.synchronize do
22 | git =
23 | if File.directory?(path)
24 | g = ::Git.open(path)
25 | g.pull
26 | g
27 | else
28 | ::Git.clone("https://github.com/omnigres/omnigres", path)
29 | end
30 | git.checkout(revision) if revision
31 | @git = git
32 | end
33 | end
34 |
35 | attr_reader :git
36 |
37 | def extension_versions
38 | process_git_log
39 | @@extensions[@git.log.first.sha]
40 | end
41 |
42 | def extension_git_revisions
43 | process_git_log
44 | @@git_revisions[@git.log.first.sha]
45 | end
46 |
47 | private
48 |
49 | def process_git_log
50 | return if @@extensions[@git.log.first.sha]
51 |
52 | # Direct merge commits into master
53 | direct_master_merges = @git.lib.send(:command, "rev-list", "master", "--first-parent").split.map
54 |
55 | # Get versions.txt from all direct merges (we don't want to consider what's inside a merge
56 | # as it may contain versions we never released)
57 | # This is going to create a hash table [name, sha] => version
58 | versions_map = @git.log(:all).path("versions.txt").select { |c| direct_master_merges.include?(c.sha) }.each_with_object({}) do |c, h|
59 | lines = @git.show(c, "versions.txt").split
60 | lines.each do |l|
61 | ext, ver = l.split("=")
62 | h[[ext, c.sha]] = Pgpm::Package::Version.new(ver)
63 | end
64 | end
65 |
66 | # Hash mapping extension names to a list of versions
67 | # name => [versions]
68 | @@extensions[@git.log.first.sha] = versions_map.group_by { |(name, _sha), _ver| name }
69 | .transform_values { |entries| entries.map { |_key, version| version }.uniq }
70 |
71 | # Hash mapping extension versions to SHAs
72 | # [name][ver] => sha
73 | # Note that we're getting the latest merges that contain this version – it doesn't mean that these
74 | # are the merges where those versions were introduced. But that's okay because if they are there,
75 | # they are buildable at least as of those merges and possible at the HEAD of master.
76 | @@git_revisions[@git.log.first.sha] = versions_map.each_with_object({}) do |((name, sha), version), result|
77 | result[name] ||= {}
78 | result[name][version] = sha
79 | end
80 | end
81 | end
82 | end
83 |
--------------------------------------------------------------------------------
/packages/omnigres/omni.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class Omni < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Advanced adapter for Postgres extensions"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_auth.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniAuth < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Authentication framework"
9 | end
10 |
11 | def build_dependencies
12 | super + ["zlib-devel", Pgpm::Postgres::Distribution.in_scope.package_for(Pgpm::Contrib::Pgcrypto[:latest])]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_aws.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniAws < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "AWS APIs"
9 | end
10 |
11 | def build_dependencies
12 | super + ["zlib-devel", Pgpm::Postgres::Distribution.in_scope.package_for(Pgpm::Contrib::Pgcrypto[:latest])]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_cloudevents.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniCloudevents < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "CloudEvents support"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_containers.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniContainers < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Managing containers"
9 | end
10 |
11 | def build_dependencies
12 | super + ["zlib-devel"]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_http.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniHttp < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Common HTTP types library"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_httpc.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniHttpc < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "HTTP client"
9 | end
10 |
11 | def build_dependencies
12 | super + ["zlib-devel"]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_httpd.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniHttpd < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "HTTP web server"
9 | end
10 |
11 | def build_dependencies
12 | super + %w[zlib-devel flex bison]
13 | end
14 |
15 | def depends_on_omni?
16 | true
17 | end
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_id.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniId < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Identity types"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_json.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniJson < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "JSON toolkit"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_ledger.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniLedger < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Financial ledgering and accounting"
9 | end
10 |
11 | def depends_on_omni?
12 | true
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_manifest.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniManifest < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Improved extension installation"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_mimetypes.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniMimetypes < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "MIME types and file extensions"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_os.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniOs < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Access to the operating system"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_polyfill.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniPolyfill < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Provides polyfills for older versions of Postgres"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_python.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniPython < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "First-class Python Development Experience"
9 | end
10 |
11 | def build_dependencies
12 | super + [Pgpm::Postgres::Distribution.in_scope.package_for(Pgpm::Contrib::Plpython3u[:latest])]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_regex.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniRegex < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Feature-rich regular expresssions"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_schema.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniSchema < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Application schema management"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_seq.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniSeq < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Extended Postgres sequence tooling"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_session.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniSession < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Session management"
9 | end
10 |
11 | def build_dependencies
12 | super + %w[zlib-devel flex bison]
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_sql.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniSql < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Programmatic access to SQL"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_txn.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniTxn < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Advanced transaction management"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_types.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniTypes < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Advanced Postgres typing techniques"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_var.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniVar < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Variable management"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_vfs.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniVfs < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Virtual File System"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_vfs_types_v1.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniVfsTypesV1 < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Virtual File System API"
9 | end
10 |
11 | def requires
12 | # FIXME: this handles the special case of this extension being in
13 | # the same folder as omni_vfs.
14 | # In order to configure it, all dependencies of omni_vfs, save for omni_vfs_types_v1,
15 | # must be included.
16 | Pgpm::Package["omnigres/omni_vfs"][:latest].requires.reject { |p| p.name == name }
17 | end
18 |
19 | def native?
20 | # This extension shares the directory with `omni_vfs` which has .c files,
21 | # but it is not a native-code extension itself.
22 | false
23 | end
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_web.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniWeb < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "Web stack primitives"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_xml.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniXml < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "XML toolkit"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnigres/omni_yaml.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Omnigres
4 | class OmniYaml < Pgpm::Package
5 | include Package
6 |
7 | def summary
8 | "YAML toolkit"
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/packages/omnisketch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Omnisketch < Pgpm::Package
4 | github "tvondra/omnisketch"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/oracle_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class OracleFdw < Pgpm::Package
4 | github "laurenz/oracle_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/orafce.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Orafce < Pgpm::Package
4 | github "orafce/orafce"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pagevis.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pagevis < Pgpm::Package
4 | github "hollobon/pagevis"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/passwordcheck_cracklib.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PasswordcheckCracklib < Pgpm::Package
4 | github "devrimgunduz/passwordcheck_cracklib"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/periods.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Periods < Pgpm::Package
4 | github "xocolatl/periods"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/permuteseq.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Permuteseq < Pgpm::Package
4 | github "dverite/permuteseq"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_analytics.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgAnalytics < Pgpm::Package
4 | github "paradedb/pg_analytics"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_auditor.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgAuditor < Pgpm::Package
4 | github "kouber/pg_auditor"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_auth_mon.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgAuthMon < Pgpm::Package
4 | github "RafiaSabih/pg_auth_mon"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_background.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgBackground < Pgpm::Package
4 | github "vibhorkum/pg_background"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_base58.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgBase58 < Pgpm::Package
4 | github "Fell-x27/pg_base58"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_bestmatch.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgBestmatch < Pgpm::Package
4 | github "tensorchord/pg_bestmatch.rs"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_bigm.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgBigm < Pgpm::Package
4 | github "pgbigm/pg_bigm"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_bulkload.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgBulkload < Pgpm::Package
4 | github "ossc-db/pg_bulkload"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_cardano.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgCardano < Pgpm::Package
4 | github "Fell-x27/pg_cardano"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_catcheck.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgCatcheck < Pgpm::Package
4 | github "EnterpriseDB/pg_catcheck"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_cheat_funcs.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgCheatFuncs < Pgpm::Package
4 | github "MasaoFujii/pg_cheat_funcs"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_checksums.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgChecksums < Pgpm::Package
4 | github "credativ/pg_checksums"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_crash.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgCrash < Pgpm::Package
4 | github "cybertec-postgresql/pg_crash"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_cron.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgCron < Pgpm::Package
4 | github "citusdata/pg_cron"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_dbms_job.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDbmsJob < Pgpm::Package
4 | github "MigOpsRepos/pg_dbms_job"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_dbms_lock.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDbmsLock < Pgpm::Package
4 | github "HexaCluster/pg_dbms_lock"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_dbms_metadata.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDbmsMetadata < Pgpm::Package
4 | github "HexaCluster/pg_dbms_metadata"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_dirtyread.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDirtyread < Pgpm::Package
4 | github "df7cb/pg_dirtyread"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_drop_events.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDropEvents < Pgpm::Package
4 | github "bolajiwahab/pg_drop_events"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_duckdb.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDuckdb < Pgpm::Package
4 | github "duckdb/pg_duckdb"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_duration.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgDuration < Pgpm::Package
4 | github "jkosh44/pg_duration"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_extra_time.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgExtraTime < Pgpm::Package
4 | github "bigsmoke/pg_extra_time"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_fact_loader.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgFactLoader < Pgpm::Package
4 | github "enova/pg_fact_loader"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_failover_slots.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgFailoverSlots < Pgpm::Package
4 | github "EnterpriseDB/pg_failover_slots"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_fio.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgFio < Pgpm::Package
4 | github "csimsek/pgsql-fio"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_fkpart.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgFkpart < Pgpm::Package
4 | github "lemoineat/pg_fkpart"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_geohash.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgGeohash < Pgpm::Package
4 | github "jistok/pg_geohash"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_graphql.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgGraphql < Pgpm::Package
4 | github "supabase/pg_graphql"
5 |
6 | def summary
7 | "GraphQL support for PostgreSQL"
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/packages/pg_hashids.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgHashids < Pgpm::Package
4 | github "iCyberon/pg_hashids"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_hashlib.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgHashlib < Pgpm::Package
4 | github "markokr/pghashlib"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_hint_plan.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgHintPlan < Pgpm::Package
4 | github "ossc-db/pg_hint_plan"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_html5_email_address.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgHtml5EmailAddress < Pgpm::Package
4 | github "bigsmoke/pg_html5_email_address"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_idkit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgIdkit < Pgpm::Package
4 | github "VADOSWARE/pg_idkit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_incremental.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgIncremental < Pgpm::Package
4 | github "crunchydata/pg_incremental"
5 |
6 | def requires
7 | super + [Pgpm::Package["pg_cron"][:latest]]
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/packages/pg_ivm.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgIvm < Pgpm::Package
4 | github "sraoss/pg_ivm"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_jobmon.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgJobmon < Pgpm::Package
4 | github "omniti-labs/pg_jobmon"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_jsonschema.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgJsonschema < Pgpm::Package
4 | github "supabase/pg_jsonschema"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_later.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgLater < Pgpm::Package
4 | github "tembo-io/pg_later"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_math.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgMath < Pgpm::Package
4 | github "chanukyasds/pg_math"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_mooncake.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgMooncake < Pgpm::Package
4 | github "Mooncake-Labs/pg_mooncake"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_net.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgNet < Pgpm::Package
4 | github "supabase/pg_net"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_orphaned.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgOrphaned < Pgpm::Package
4 | github "bdrouvot/pg_orphaned"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_parquet.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgParquet < Pgpm::Package
4 | github "CrunchyData/pg_parquet"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_partman.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgPartman < Pgpm::Package
4 | github "pgpartman/pg_partman"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_permissions.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgPermissions < Pgpm::Package
4 | github "cybertec-postgresql/pg_permissions"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_polyline.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgPolyline < Pgpm::Package
4 | github "yihong0618/pg_polyline"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_proctab.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgProctab < Pgpm::Package
4 | github "markwkm/pg_proctab"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_profile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgProfile < Pgpm::Package
4 | github "zubkov-andrei/pg_profile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_protobuf.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgProtobuf < Pgpm::Package
4 | github "afiskon/pg_protobuf"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_qualstats.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgQualstats < Pgpm::Package
4 | github "powa-team/pg_qualstats"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_rational.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgRational < Pgpm::Package
4 | github "begriffs/pg_rational"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_readme.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgReadme < Pgpm::Package
4 | github "bigsmoke/pg_readme"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_readonly.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgReadonly < Pgpm::Package
4 | github "pierreforstmann/pg_readonly"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_relusage.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgRelusage < Pgpm::Package
4 | github "adept/pg_relusage"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_repack.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgRepack < Pgpm::Package
4 | github "reorg/pg_repack"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_rrule.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgRrule < Pgpm::Package
4 | github "petropavel13/pg_rrule"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_savior.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSavior < Pgpm::Package
4 | github "viggy28/pg_savior"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_search.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSearch < Pgpm::Package
4 | github "paradedb/paradedb"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_session_jwt.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSessionJwt < Pgpm::Package
4 | github "neondatabase/pg_session_jwt"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_show_plans.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgShowPlans < Pgpm::Package
4 | github "cybertec-postgresql/pg_show_plans"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_similarity.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSimilarity < Pgpm::Package
4 | github "eulerto/pg_similarity"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_smtp_client.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSmtpClient < Pgpm::Package
4 | github "brianpursley/pg_smtp_client"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_snakeoil.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSnakeoil < Pgpm::Package
4 | github "credativ/pg_snakeoil"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_sphere.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSphere < Pgpm::Package
4 | github "postgrespro/pgsphere"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_sqlog.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSqlog < Pgpm::Package
4 | github "kouber/pg_sqlog"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_squeeze.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSqueeze < Pgpm::Package
4 | github "cybertec-postgresql/pg_squeeze"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_stat_kcache.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgStatKcache < Pgpm::Package
4 | github "powa-team/pg_stat_kcache"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_stat_monitor.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgStatMonitor < Pgpm::Package
4 | github "percona/pg_stat_monitor"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_statement_rollback.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgStatementRollback < Pgpm::Package
4 | github "lzlabs/pg_statement_rollback"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_store_plans.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgStorePlans < Pgpm::Package
4 | github "ossc-db/pg_store_plans"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_strom.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgStrom < Pgpm::Package
4 | github "heterodb/pg-strom"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_summarize.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgSummarize < Pgpm::Package
4 | github "HexaCluster/pg_summarize"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_task.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTask < Pgpm::Package
4 | github "RekGRpth/pg_task"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_tde.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTde < Pgpm::Package
4 | github "Percona-Lab/pg_tde"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_text_semver.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTextSemver < Pgpm::Package
4 | github "bigsmoke/pg_text_semver"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_tiktoken.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTiktoken < Pgpm::Package
4 | github "kelvich/pg_tiktoken"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_tle.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTle < Pgpm::Package
4 | github "aws/pg_tle"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_top.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTop < Pgpm::Package
4 | git "https://gitlab.com/pg_top/pg_top"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_track_settings.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgTrackSettings < Pgpm::Package
4 | github "rjuju/pg_track_settings"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_upless.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgUpless < Pgpm::Package
4 | github "rodo/pg_upless"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_uuidv7.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgUuidv7 < Pgpm::Package
4 | github "fboulnois/pg_uuidv7"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_wait_sampling.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgWaitSampling < Pgpm::Package
4 | github "postgrespro/pg_wait_sampling"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pg_xenophile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgXenophile < Pgpm::Package
4 | github "bigsmoke/pg_xenophile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgaudit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgaudit < Pgpm::Package
4 | github "pgaudit/pgaudit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgauditlogtofile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgauditlogtofile < Pgpm::Package
4 | github "fmbiete/pgauditlogtofile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgautofailover.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgautofailover < Pgpm::Package
4 | github "hapostgres/pg_auto_failover"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgbouncer_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgbouncerFdw < Pgpm::Package
4 | github "CrunchyData/pgbouncer_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgcozy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgcozy < Pgpm::Package
4 | github "vventirozos/pgcozy"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgdd.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgdd < Pgpm::Package
4 | github "rustprooflabs/pgdd"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgemailaddr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgemailaddr < Pgpm::Package
4 | github "petere/pgemailaddr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgextwlist.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgextwlist < Pgpm::Package
4 | github "dimitri/pgextwlist"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgfaceting.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgfaceting < Pgpm::Package
4 | github "cybertec-postgresql/pgfaceting"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgfincore.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgfincore < Pgpm::Package
4 | github "klando/pgfincore"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgjwt.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgjwt < Pgpm::Package
4 | github "michelp/pgjwt"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgl_ddl_deploy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PglDdlDeploy < Pgpm::Package
4 | github "enova/pgl_ddl_deploy"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pglite_fusion.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgliteFusion < Pgpm::Package
4 | github "frectonz/pglite-fusion"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pglogical.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pglogical < Pgpm::Package
4 | github "2ndQuadrant/pglogical"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pglogical_origin.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PglogicalOrigin < Pgpm::Package
4 | github "2ndQuadrant/pglogical"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pglogical_ticker.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PglogicalTicker < Pgpm::Package
4 | github "enova/pglogical_ticker"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgmemcache.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgmemcache < Pgpm::Package
4 | github "ohmu/pgmemcache"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgmeminfo.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgmeminfo < Pgpm::Package
4 | github "okbob/pgmeminfo"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgml.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgml < Pgpm::Package
4 | github "postgresml/postgresml"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgmp.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgmp < Pgpm::Package
4 | github "dvarrazzo/pgmp", tag_prefix: "rel-"
5 |
6 | def build_dependencies
7 | super + %w[gmp-devel]
8 | end
9 |
10 | def dependencies
11 | super + %w[gmp]
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/packages/pgmq.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgmq < Pgpm::Package
4 | github "tembo-io/pgmq"
5 |
6 | def source
7 | Pathname(File.join(super, "pgmq-extension"))
8 | end
9 |
10 | def pgxn_meta_json_path
11 | File.join(source, "META.json.in")
12 | end
13 |
14 | def pgxn_meta_json
15 | @pgxn_meta_json ||= Oj.load(File.read(pgxn_meta_json_path).gsub(/@@VERSION@@/, version.to_s))
16 | end
17 |
18 | def source_url_directory_name
19 | "pgmq-#{version}/pgmq-extension"
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/packages/pgnodemx.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgnodemx < Pgpm::Package
4 | github "CrunchyData/pgnodemx"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgpcre.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgpcre < Pgpm::Package
4 | github "petere/pgpcre"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgpdf.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgpdf < Pgpm::Package
4 | github "Florents-Tselai/pgpdf"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgq.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgq < Pgpm::Package
4 | github "pgq/pgq"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgqr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgqr < Pgpm::Package
4 | github "AbdulYadi/pgqr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgroonga.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgroonga < Pgpm::Package
4 | github "pgroonga/pgroonga"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgroonga_database.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgroongaDatabase < Pgpm::Package
4 | github "pgroonga/pgroonga"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgrouting.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgrouting < Pgpm::Package
4 | github "pgRouting/pgrouting"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgsmcrypto.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgsmcrypto < Pgpm::Package
4 | github "zhuobie/pgsmcrypto"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgsodium.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgsodium < Pgpm::Package
4 | github "michelp/pgsodium"
5 |
6 | def build_dependencies
7 | deps = case Pgpm::OS.in_scope.class.name
8 | when "debian", "ubuntu"
9 | ["libsodium-dev (>= 1.0.18)"]
10 | when "rocky+epel-9", "redhat", "fedora"
11 | ["libsodium-devel >= 1.0.18"]
12 | end
13 | super + deps
14 | end
15 |
16 | def dependencies
17 | deps = case Pgpm::OS.in_scope.class.name
18 | when "debian", "ubuntu"
19 | ["libsodium (>= 1.0.18)"]
20 | when "rocky+epel-9", "redhat", "fedora"
21 | ["libsodium >= 1.0.18"]
22 | end
23 | super + deps
24 | end
25 |
26 | def broken?
27 | version >= "3.0.0" && Pgpm::Postgres::Distribution.in_scope.major_version < 14
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/packages/pgsql_tweaks.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PgsqlTweaks < Pgpm::Package
4 | github "sjstoelting/pgsql-tweaks"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgtap.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgtap < Pgpm::Package
4 | github "theory/pgtap"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgtt.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgtt < Pgpm::Package
4 | github "darold/pgtt"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pguecc.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pguecc < Pgpm::Package
4 | github "ameensol/pg-ecdsa"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pgvector.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pgvector < Pgpm::Package
4 | github "pgvector/pgvector"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plan_filter.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PlanFilter < Pgpm::Package
4 | github "pgexperts/pg_plan_filter"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pldbgapi.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pldbgapi < Pgpm::Package
4 | github "EnterpriseDB/pldebugger"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pljava.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pljava < Pgpm::Package
4 | github "tada/pljava"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pllua.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pllua < Pgpm::Package
4 | github "pllua/pllua"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plluau.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plluau < Pgpm::Package
4 | github "pllua/pllua"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plpgsql_check.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "semver_dialects"
4 |
5 | class PlpgsqlCheck < Pgpm::Package
6 | github "okbob/plpgsql_check"
7 | end
8 |
--------------------------------------------------------------------------------
/packages/plprofiler.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plprofiler < Pgpm::Package
4 | github "bigsql/plprofiler"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plproxy.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plproxy < Pgpm::Package
4 | github "plproxy/plproxy"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plprql.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plprql < Pgpm::Package
4 | github "kaspermarstal/plprql"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plr < Pgpm::Package
4 | github "postgres-plr/plr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plsh.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plsh < Pgpm::Package
4 | github "petere/plsh"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/plv8.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Plv8 < Pgpm::Package
4 | github "plv8/plv8"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pointcloud.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Pointcloud < Pgpm::Package
4 | github "pgpointcloud/pointcloud"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pointcloud_postgis.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PointcloudPostgis < Pgpm::Package
4 | github "pgpointcloud/pointcloud"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/powa.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Powa < Pgpm::Package
4 | github "powa-team/powa"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/pre_prepare.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class PrePrepare < Pgpm::Package
4 | github "dimitri/preprepare"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/prefix.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Prefix < Pgpm::Package
4 | github "dimitri/prefix"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/prioritize.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Prioritize < Pgpm::Package
4 | github "schmiddy/pg_prioritize"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/q3c.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Q3c < Pgpm::Package
4 | github "segasai/q3c"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/quantile.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Quantile < Pgpm::Package
4 | github "tvondra/quantile"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/random.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Random < Pgpm::Package
4 | github "tvondra/random"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/rdkit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Rdkit < Pgpm::Package
4 | github "rdkit/rdkit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/redis.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Redis < Pgpm::Package
4 | github "brettlaforge/pg_redis_pubsub"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/redis_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class RedisFdw < Pgpm::Package
4 | github "pg-redis-fdw/redis_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/repmgr.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Repmgr < Pgpm::Package
4 | github "EnterpriseDB/repmgr"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/roaringbitmap.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Roaringbitmap < Pgpm::Package
4 | github "ChenHuajun/pg_roaringbitmap"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/rum.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Rum < Pgpm::Package
4 | github "postgrespro/rum"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/safeupdate.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Safeupdate < Pgpm::Package
4 | github "eradman/pg-safeupdate"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/schedoc.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Schedoc < Pgpm::Package
4 | github "ZeroGachis/pg_schedoc"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/semver.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Semver < Pgpm::Package
4 | github "theory/pg-semver"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/sequential_uuids.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SequentialUuids < Pgpm::Package
4 | github "tvondra/sequential-uuids"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/session_variable.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SessionVariable < Pgpm::Package
4 | github "splendiddata/session_variable"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/set_user.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SetUser < Pgpm::Package
4 | github "pgaudit/set_user"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/shacrypt.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Shacrypt < Pgpm::Package
4 | github "dverite/postgres-shacrypt"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/smlar.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Smlar < Pgpm::Package
4 | github "jirutka/smlar"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/sqlite_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SqliteFdw < Pgpm::Package
4 | github "pgspider/sqlite_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/sslutils.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Sslutils < Pgpm::Package
4 | github "EnterpriseDB/sslutils"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/supabase_vault.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SupabaseVault < Pgpm::Package
4 | github "supabase/vault"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/supautils.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Supautils < Pgpm::Package
4 | github "supabase/supautils"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/system_stats.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class SystemStats < Pgpm::Package
4 | github "EnterpriseDB/system_stats"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/table_log.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class TableLog < Pgpm::Package
4 | github "df7cb/table_log"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/table_version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class TableVersion < Pgpm::Package
4 | github "linz/postgresql-tableversion"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/tdigest.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Tdigest < Pgpm::Package
4 | github "tdunning/t-digest"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/tds_fdw.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class TdsFdw < Pgpm::Package
4 | github "tds-fdw/tds_fdw"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/temporal_tables.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "semver_dialects"
4 |
5 | class TemporalTables < Pgpm::Package
6 | github "arkhipov/temporal_tables"
7 | end
8 |
--------------------------------------------------------------------------------
/packages/timeit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Timeit < Pgpm::Package
4 | github "joelonsql/pg-timeit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/timescale/timescaledb.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Timescale
4 | class Timescaledb < Pgpm::Package
5 | github "timescale/timescaledb"
6 |
7 | def self.package_versions
8 | # TODO: ensure non-compatible versions are handled better
9 | # in version comparison
10 | # For now, this helps with handling `loader-2.11.0p1` version
11 | super.select { |v| v.to_s =~ /^(\d+\.\d+\.\d+)$/ }
12 | end
13 |
14 | def description
15 | "An open-source time-series SQL database optimized for fast ingest and " \
16 | "complex queries"
17 | end
18 |
19 | def summary
20 | "TimescaleDB is an open-source database designed to make SQL " \
21 | "scalable for time-series data. It is engineered up from PostgreSQL " \
22 | "and packaged as a PostgreSQL extension, providing automatic " \
23 | "partitioning across time and space (partitioning key), as well as " \
24 | "full SQL support."
25 | end
26 |
27 | def dependencies
28 | deps = case Pgpm::OS.in_scope.class.name
29 | when "rocky+epel-9", "redhat", "fedora"
30 | ["openssl"]
31 | end
32 | super + deps
33 | end
34 |
35 | def build_dependencies
36 | deps = case Pgpm::OS.in_scope.class.name
37 | when "debian", "ubuntu"
38 | %w[libssl-dev cmake]
39 | when "rocky+epel-9", "redhat", "fedora"
40 | %w[openssl-devel cmake]
41 | end
42 | super + deps
43 | end
44 |
45 | def configure_steps
46 | case Pgpm::OS.in_scope.class.name
47 | when "debian", "ubuntu"
48 | ["dh_auto_configure -- -DCMAKE_BUILD_TYPE=\"Release\""]
49 | else
50 | super
51 | end
52 | end
53 |
54 | def build_steps
55 | case Pgpm::OS.in_scope.class.name
56 | when "debian", "ubuntu"
57 | ["dh_auto_build"]
58 | when "rocky+epel-9", "redhat", "fedora"
59 | [
60 | "./bootstrap -DPG_CONFIG=$PG_CONFIG #{bootstrap_flags.map { |f| "-D#{f}" }.join(" ")}",
61 | "cmake --build build --parallel"
62 | ]
63 | end
64 | end
65 |
66 | def install_steps
67 | case Pgpm::OS.in_scope.class.name
68 | when "rocky+epel-9", "redhat", "fedora"
69 | ["DESTDIR=$PGPM_INSTALL_ROOT cmake --build build --target install"]
70 | else
71 | super
72 | end
73 | end
74 |
75 | protected
76 |
77 | def bootstrap_flags
78 | []
79 | end
80 | end
81 | end
82 |
--------------------------------------------------------------------------------
/packages/timescale/timescaledb_apache2.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | module Timescale
4 | # TODO: do we want this "subpackage" to be some kind of "flavour" in pgpm?
5 | class TimescaledbApache2 < Timescaledb
6 | # TODO: can pgpm handle subclassing here better?
7 | github "timescale/timescaledb"
8 |
9 | def extension_name
10 | "timescaledb"
11 | end
12 |
13 | def source_url_directory_name
14 | "timescaledb-2.17.2"
15 | end
16 |
17 | def license
18 | "Apache 2.0"
19 | end
20 |
21 | protected
22 |
23 | def bootstrap_flags
24 | ["APACHE_ONLY=1"]
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/packages/timescaledb_toolkit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class TimescaledbToolkit < Pgpm::Package
4 | github "timescale/timescaledb-toolkit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/timeseries.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Timeseries < Pgpm::Package
4 | github "tembo-io/pg_timeseries"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/timestamp9.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Timestamp9 < Pgpm::Package
4 | github "optiver/timestamp9"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/toastinfo.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Toastinfo < Pgpm::Package
4 | github "credativ/toastinfo"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/topn.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Topn < Pgpm::Package
4 | github "citusdata/postgresql-topn"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/uint.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Uint < Pgpm::Package
4 | github "petere/pguint"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/uint128.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Uint128 < Pgpm::Package
4 | github "pg-uint/pg-uint128"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/unit.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Unit < Pgpm::Package
4 | github "df7cb/postgresql-unit"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/uri.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Uri < Pgpm::Package
4 | github "petere/pguri"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/url_encode.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class UrlEncode < Pgpm::Package
4 | github "okbob/url_encode"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/vasco.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Vasco < Pgpm::Package
4 | github "Florents-Tselai/vasco"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/vchord.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Vchord < Pgpm::Package
4 | github "tensorchord/VectorChord"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/vectorize.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Vectorize < Pgpm::Package
4 | github "tembo-io/pg_vectorize"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/vectorscale.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Vectorscale < Pgpm::Package
4 | github "timescale/pgvectorscale"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/wal2json.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Wal2json < Pgpm::Package
4 | github "eulerto/wal2json"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/wal2mongo.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Wal2mongo < Pgpm::Package
4 | github "HighgoSoftware/wal2mongo"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/wrappers.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Wrappers < Pgpm::Package
4 | github "supabase/wrappers"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/xxhash.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Xxhash < Pgpm::Package
4 | github "hatarist/pg_xxhash"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/zhparser.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Zhparser < Pgpm::Package
4 | github "amutu/zhparser"
5 | end
6 |
--------------------------------------------------------------------------------
/packages/zstd.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | class Zstd < Pgpm::Package
4 | github "grahamedgecombe/pgzstd"
5 | end
6 |
--------------------------------------------------------------------------------
/pgpm.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require_relative "lib/pgpm/version"
4 |
5 | Gem::Specification.new do |spec|
6 | spec.name = "pgpm"
7 | spec.version = Pgpm::VERSION
8 | spec.authors = ["Yurii Rashkovskii"]
9 | spec.email = ["yrashk@gmail.com"]
10 |
11 | spec.summary = "Postgres Package Manager"
12 | spec.homepage = "https://postgres.pm"
13 | spec.license = "Apache-2.0"
14 | spec.required_ruby_version = ">= 3.3.0"
15 |
16 | # spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
17 |
18 | spec.metadata["homepage_uri"] = spec.homepage
19 | spec.metadata["source_code_uri"] = "https://github.com/postgres-pm/postgres-om"
20 | # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
21 |
22 | # Specify which files should be added to the gem when it is released.
23 | spec.files = Dir.glob(["exe/*", "lib/**/**", "sig/**/**"])
24 | spec.bindir = "exe"
25 | spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
26 | spec.require_paths = ["lib"]
27 |
28 | # Uncomment to register a new dependency of your gem
29 | # spec.add_dependency "example-gem", "~> 1.0"
30 |
31 | spec.add_dependency "dry-cli", "~> 1.1.0"
32 | spec.add_dependency "dry-inflector", "~> 1.1.0"
33 | spec.add_dependency "git", "~> 2.3.0"
34 | spec.add_dependency "lspace", "~> 0.14"
35 | spec.add_dependency "minitar", "~> 1.0.2"
36 | spec.add_dependency "nokogiri", "~> 1.16"
37 | spec.add_dependency "oj", "~> 3.16.6"
38 | spec.add_dependency "parallel", "~> 1.26.3"
39 | spec.add_dependency "perfect_toml", "~> 0.9.0"
40 | spec.add_dependency "progress", "~> 3.6.0"
41 | spec.add_dependency "semver_dialects", "~> 3.4.3"
42 | spec.add_dependency "tty-command", "~> 0.10.1"
43 | spec.add_dependency "xdg", [">= 8.7.0", "< 10"]
44 | spec.add_dependency "zeitwerk", "~> 2.6.18"
45 | spec.add_dependency "zlib", "~> 3.1.1"
46 |
47 | # For more information and examples about making a new gem, check out our
48 | # guide at: https://bundler.io/guides/creating_gem.html
49 | end
50 |
--------------------------------------------------------------------------------
/pigsty.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require "bundler/setup"
5 | require "active_support/core_ext/string/inflections"
6 | require "pgpm"
7 | require "csv"
8 | require "open-uri"
9 |
10 | Pgpm.load_packages
11 |
12 | URI.open("https://raw.githubusercontent.com/pgsty/extension/refs/heads/main/data/pigsty.csv") do |f|
13 | i = 0
14 | CSV.foreach(f, headers: true) do |row|
15 | next unless row["url"] =~ /github/ || row["url"] =~ /gitlab/
16 |
17 | origin = row["url"]
18 | if row["url"] =~ /github/
19 | github = origin.match(%r{https://github\.com/([^/]+)/([^/]+)}).captures.join("/")
20 | origin = "github \"#{github}\""
21 | else
22 | origin = "git \"#{origin}\""
23 | end
24 | name = row["name"]
25 |
26 | next if Pgpm::Package.find do |pkg|
27 | origin =~ /github/ &&
28 | pkg.respond_to?(:github_config) && pkg.github_config&.name == github
29 | end
30 |
31 | next if File.exist?("packages/#{name}.rb")
32 |
33 | i += 1
34 | classname = name.camelize
35 | new_class = <<~CLASS
36 | class #{classname} < Pgpm::Package
37 | #{origin}
38 | end
39 | CLASS
40 | File.write("packages/#{name}.rb", new_class)
41 | puts name
42 | end
43 | puts "#{i} packages imported"
44 | end
45 |
--------------------------------------------------------------------------------
/sig/pgpm.rbs:
--------------------------------------------------------------------------------
1 | module Pgpm
2 | VERSION: String
3 | # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4 | end
5 |
--------------------------------------------------------------------------------
/test/test_helper.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "pgpm"
4 |
5 | require "minitest/autorun"
6 |
--------------------------------------------------------------------------------
/test/test_pgpm.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class TestPgpm < Minitest::Test
6 | def test_that_it_has_a_version_number
7 | refute_nil ::Pgpm::VERSION
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/test/test_pgpm_package_version.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | require "test_helper"
4 |
5 | class TestPgpmPackageVersion < Minitest::Test
6 | def test_converts_to_string
7 | assert_equal Pgpm::Package::Version.new("1.2.103").to_s, "1.2.103"
8 | end
9 |
10 | def test_equality_with_string
11 | assert_equal Pgpm::Package::Version.new("1.2.103"), "1.2.103"
12 | end
13 |
14 | def test_hashes
15 | assert_equal ({ Pgpm::Package::Version.new("1.2.103") => "yes" }[Pgpm::Package::Version.new("1.2.103")]), "yes"
16 | end
17 |
18 | def test_compares
19 | assert Pgpm::Package::Version.new("1.2.103") > Pgpm::Package::Version.new("1.2.3")
20 | end
21 | end
22 |
--------------------------------------------------------------------------------