Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package obs-service-node_modules for
openSUSE:Factory checked in at 2026-09-22 15:53:53
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/obs-service-node_modules (Old)
and /work/SRC/openSUSE:Factory/.obs-service-node_modules.new.383539 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "obs-service-node_modules"
Tue Sep 22 15:53:53 2026 rev:10 rq:1379677 version:3.0.19
Changes:
--------
---
/work/SRC/openSUSE:Factory/obs-service-node_modules/obs-service-node_modules.changes
2026-09-07 11:33:20.545435945 +0200
+++
/work/SRC/openSUSE:Factory/.obs-service-node_modules.new.383539/obs-service-node_modules.changes
2026-09-22 15:55:38.784245730 +0200
@@ -1,0 +2,8 @@
+Tue Sep 22 12:24:24 UTC 2026 - Adam Majer <[email protected]>
+
+- Update to version 3.0.19:
+ * Add omit-optional service parameter and filter optional dependencies
+ * fix test: update download path to node_modules subdirectory
+- Update maintainer and standards of Debian package
+
+-------------------------------------------------------------------
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ obs-service-node_modules.spec ++++++
--- /var/tmp/diff_new_pack.bDzeYT/_old 2026-09-22 15:55:39.500275228 +0200
+++ /var/tmp/diff_new_pack.bDzeYT/_new 2026-09-22 15:55:39.501275269 +0200
@@ -17,7 +17,7 @@
Name: obs-service-node_modules
-Version: 3.0.10
+Version: 3.0.19
Release: 0
Summary: OBS service to download node_modules specified in
package-lock.json
License: MIT
++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.bDzeYT/_old 2026-09-22 15:55:39.557277576 +0200
+++ /var/tmp/diff_new_pack.bDzeYT/_new 2026-09-22 15:55:39.560277700 +0200
@@ -1,6 +1,6 @@
<servicedata>
<service name="tar_scm">
<param
name="url">http://github.com/openSUSE/obs-service-node_modules.git</param>
- <param
name="changesrevision">801b530fdf127a2bd9a3af8050d642af876e4543</param></service></servicedata>
+ <param
name="changesrevision">1d1be6f3148ca716f69cdc419e4fac48fcd5107d</param></service></servicedata>
(No newline at EOF)
++++++ debian.changelog ++++++
--- /var/tmp/diff_new_pack.bDzeYT/_old 2026-09-22 15:55:39.581278565 +0200
+++ /var/tmp/diff_new_pack.bDzeYT/_new 2026-09-22 15:55:39.586278771 +0200
@@ -1,4 +1,4 @@
-obs-service-node-modules (3.0.10-0) unstable; urgency=medium
+obs-service-node-modules (3.0.19-0) unstable; urgency=medium
* Fix install directory
++++++ debian.dsc ++++++
--- /var/tmp/diff_new_pack.bDzeYT/_old 2026-09-22 15:55:39.642281078 +0200
+++ /var/tmp/diff_new_pack.bDzeYT/_new 2026-09-22 15:55:39.645281202 +0200
@@ -1,10 +1,10 @@
Format: 3.0 (quilt)
Source: obs-service-node-modules
-Version: 3.0.10-0
+Version: 3.0.19-0
Binary: obs-service-node-modules
-Maintainer: Ilya Stolyarov <[email protected]>
+Maintainer: Adam Majer <[email protected]>
Architecture: all
-Standards-Version: 3.7.2
+Standards-Version: 4.7.4
Build-Depends: debhelper,
python3-lxml
++++++ obs-service-node_modules.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/obs-service-node_modules/.github/workflows/integration_tests.yml
new/obs-service-node_modules/.github/workflows/integration_tests.yml
--- old/obs-service-node_modules/.github/workflows/integration_tests.yml
2026-09-04 13:44:18.000000000 +0200
+++ new/obs-service-node_modules/.github/workflows/integration_tests.yml
2026-09-22 14:11:01.000000000 +0200
@@ -5,6 +5,7 @@
push:
branches:
- "main"
+ - "master"
pull_request:
jobs:
@@ -13,12 +14,13 @@
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v2
- - uses: actions/setup-python@v2
- - uses: Gr1N/setup-poetry@v7
- - uses: actions/cache@v2
+ - uses: actions/checkout@v7
+ - uses: actions/setup-python@v7
+ - uses: Gr1N/setup-poetry@v9
+ - uses: actions/cache@v6
with:
path: ~/.tox
key: poetry-${{ hashFiles('poetry.lock') }}
+ - run: 'poetry install --no-root'
- run: 'poetry run pytest -vv -n auto'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/obs-service-node_modules/README.md
new/obs-service-node_modules/README.md
--- old/obs-service-node_modules/README.md 2026-09-04 13:44:18.000000000
+0200
+++ new/obs-service-node_modules/README.md 2026-09-22 14:11:01.000000000
+0200
@@ -97,3 +97,21 @@
### External Resources
https://github.com/openSUSE/npm-localhost-proxy
+
+## Testing
+
+To run the tests locally, you can use a virtual environment to install Poetry
and the project dependencies:
+
+```bash
+# Create a virtual environment for poetry
+python3 -m venv poetryvenv
+
+# Install poetry into the virtual environment
+./poetryvenv/bin/pip install poetry
+
+# Install project dependencies
+./poetryvenv/bin/poetry install --no-root
+
+# Run the tests in parallel with verbose output
+./poetryvenv/bin/poetry run pytest -vv -n auto
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/obs-service-node_modules/node_modules.py
new/obs-service-node_modules/node_modules.py
--- old/obs-service-node_modules/node_modules.py 2026-09-04
13:44:18.000000000 +0200
+++ new/obs-service-node_modules/node_modules.py 2026-09-22
14:11:01.000000000 +0200
@@ -327,12 +327,14 @@
return False
-def collect_v2_deps_recursive(d, deps):
+def collect_v2_deps_recursive(d, deps, omit_optional=False):
for module in sorted(deps):
+ entry = deps[module]
+ if omit_optional and entry.get("optional"):
+ continue
path = "/".join(("node_modules", module))
if d:
path = "/".join((d, path))
- entry = deps[module]
if "resolved" not in entry:
fetch_non_resolved_dependency_location(entry, module, path)
else:
@@ -350,11 +352,13 @@
)
if "dependencies" in entry:
- collect_v2_deps_recursive(path, entry["dependencies"])
+ collect_v2_deps_recursive(path, entry["dependencies"],
omit_optional=omit_optional)
-def process_module(module, packages):
+def process_module(module, packages, omit_optional=False):
entry = packages[module]
+ if omit_optional and entry.get("optional"):
+ return
pos = module.find("node_modules/")
if pos == -1:
# All node modules are still installed under `*/node_modules/` in some
workspace or not
@@ -383,7 +387,7 @@
)
-def collect_v3_deps(packages):
+def collect_v3_deps(packages, omit_optional=False):
deps = packages.keys()
# workspaces = packages[""]["workspaces"]
# print(workspaces)
@@ -391,7 +395,7 @@
if module == "":
continue
- process_module(module, packages)
+ process_module(module, packages, omit_optional=omit_optional)
def write_rpm_sources(fh, args):
@@ -405,13 +409,13 @@
i += 1
-def process_packagelock_file(js):
+def process_packagelock_file(js, omit_optional=False):
if not "lockfileVersion" in js:
raise Exception("Only package-lock.json with lockfileVersion=2+ are
supported")
elif js["lockfileVersion"] == 2:
- collect_v2_deps_recursive("", js["dependencies"])
+ collect_v2_deps_recursive("", js["dependencies"],
omit_optional=omit_optional)
elif js["lockfileVersion"] == 3:
- collect_v3_deps(js["packages"])
+ collect_v3_deps(js["packages"], omit_optional=omit_optional)
else:
raise Exception("Unsupported lockfileVersion found")
@@ -449,10 +453,10 @@
js = json.load(fh)
if "name" in js:
- process_packagelock_file(js)
+ process_packagelock_file(js, omit_optional=args.omit_optional)
else:
for i in js.keys():
- process_packagelock_file(js[i])
+ process_packagelock_file(js[i], omit_optional=args.omit_optional)
if args.output and args.legacy_container:
with open(_out(args.output), "w") as fh:
@@ -600,7 +604,7 @@
"checksum failure for %s %s %s %s",
fn,
algo,
- h.hexdigest,
+ h.hexdigest(),
chksum,
)
else:
@@ -753,6 +757,14 @@
help="look for cpio archive (legacy mode)",
)
parser.add_argument(
+ "--omit-optional",
+ type=str_to_bool,
+ nargs="?",
+ const=True,
+ default=False,
+ help="omit optional dependency download",
+ )
+ parser.add_argument(
"--node-dir",
metavar="DIR",
default="node_modules",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/obs-service-node_modules/node_modules.service
new/obs-service-node_modules/node_modules.service
--- old/obs-service-node_modules/node_modules.service 2026-09-04
13:44:18.000000000 +0200
+++ new/obs-service-node_modules/node_modules.service 2026-09-22
14:11:01.000000000 +0200
@@ -13,6 +13,9 @@
<parameter name="node-dir">
<description>directory to store individual tarballs in when not using
legacy-container</description>
</parameter>
+ <parameter name="omit-optional">
+ <description>omit optional dependency download</description>
+ </parameter>
<parameter name="output">
<description>write rpm source lines to that file</description>
</parameter>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/obs-service-node_modules/test_node_modules_download.py
new/obs-service-node_modules/test_node_modules_download.py
--- old/obs-service-node_modules/test_node_modules_download.py 2026-09-04
13:44:18.000000000 +0200
+++ new/obs-service-node_modules/test_node_modules_download.py 2026-09-22
14:11:01.000000000 +0200
@@ -55,8 +55,7 @@
[0], "cd /opt/playground && /bin/node_modules.py --download"
)
- tarballs =
set(auto_container.connection.file("/opt/playground/").listdir())
- tarballs.remove("package-lock.json")
+ tarballs =
set(auto_container.connection.file("/opt/playground/node_modules/").listdir())
expected_tarballs = set(
[
"acorn-7.4.1.tgz",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/obs-service-node_modules/test_parameters.py
new/obs-service-node_modules/test_parameters.py
--- old/obs-service-node_modules/test_parameters.py 2026-09-04
13:44:18.000000000 +0200
+++ new/obs-service-node_modules/test_parameters.py 2026-09-22
14:11:01.000000000 +0200
@@ -682,3 +682,145 @@
assert result_legacy.returncode == 0
spec_content_legacy = (out_dir_legacy / "mock_legacy.spec").read_text()
assert "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz#/ms-2.0.0.tgz" in
spec_content_legacy
+
+
+def test_omit_optional_v2(tmp_path):
+ """Verify that --omit-optional filters out optional dependencies in a v2
package-lock."""
+ parent_dir = tmp_path.parent
+ lock_file = parent_dir / "package-lock.json"
+ lock_file.write_text("""{
+ "name": "v2-test",
+ "version": "1.0.0",
+ "lockfileVersion": 2,
+ "requires": true,
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity":
"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "negotiator": {
+ "version": "0.6.3",
+ "resolved":
"https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity":
"sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "optional": true
+ }
+ }
+}""")
+
+ spec_file = parent_dir / "mock.spec"
+ spec_file.write_text("# NODE_MODULES BEGIN\n# NODE_MODULES END\n")
+
+ # 1. Run WITH --omit-optional
+ out_dir_omit = tmp_path / "out_omit"
+ out_dir_omit.mkdir()
+ result = subprocess.run(
+ [
+ sys.executable,
+ NODE_MODULES_PY,
+ "-i", "package-lock.json",
+ "--spec", "mock.spec",
+ "--node-dir", "node_modules",
+ "--omit-optional",
+ "--outdir", str(out_dir_omit),
+ "--download",
+ ],
+ capture_output=True,
+ text=True,
+ cwd=parent_dir,
+ )
+ assert result.returncode == 0
+ assert (out_dir_omit / "node_modules" / "ms-2.0.0.tgz").is_file()
+ assert not (out_dir_omit / "node_modules" /
"negotiator-0.6.3.tgz").exists()
+
+ # 2. Run WITHOUT --omit-optional
+ out_dir_include = tmp_path / "out_include"
+ out_dir_include.mkdir()
+ result = subprocess.run(
+ [
+ sys.executable,
+ NODE_MODULES_PY,
+ "-i", "package-lock.json",
+ "--spec", "mock.spec",
+ "--node-dir", "node_modules",
+ "--outdir", str(out_dir_include),
+ "--download",
+ ],
+ capture_output=True,
+ text=True,
+ cwd=parent_dir,
+ )
+ assert result.returncode == 0
+ assert (out_dir_include / "node_modules" / "ms-2.0.0.tgz").is_file()
+ assert (out_dir_include / "node_modules" /
"negotiator-0.6.3.tgz").is_file()
+
+
+def test_omit_optional_v3(tmp_path):
+ """Verify that --omit-optional filters out optional dependencies in a v3
package-lock."""
+ parent_dir = tmp_path.parent
+ lock_file = parent_dir / "package-lock.json"
+ lock_file.write_text("""{
+ "name": "v3-test",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "node_modules/ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity":
"sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved":
"https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity":
"sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
+ "optional": true
+ }
+ }
+}""")
+
+ spec_file = parent_dir / "mock.spec"
+ spec_file.write_text("# NODE_MODULES BEGIN\n# NODE_MODULES END\n")
+
+ # 1. Run WITH --omit-optional
+ out_dir_omit = tmp_path / "out_omit"
+ out_dir_omit.mkdir()
+ result = subprocess.run(
+ [
+ sys.executable,
+ NODE_MODULES_PY,
+ "-i", "package-lock.json",
+ "--spec", "mock.spec",
+ "--node-dir", "node_modules",
+ "--omit-optional",
+ "--outdir", str(out_dir_omit),
+ "--download",
+ ],
+ capture_output=True,
+ text=True,
+ cwd=parent_dir,
+ )
+ assert result.returncode == 0
+ assert (out_dir_omit / "node_modules" / "ms-2.0.0.tgz").is_file()
+ assert not (out_dir_omit / "node_modules" /
"negotiator-0.6.3.tgz").exists()
+
+ # 2. Run WITHOUT --omit-optional
+ out_dir_include = tmp_path / "out_include"
+ out_dir_include.mkdir()
+ result = subprocess.run(
+ [
+ sys.executable,
+ NODE_MODULES_PY,
+ "-i", "package-lock.json",
+ "--spec", "mock.spec",
+ "--node-dir", "node_modules",
+ "--outdir", str(out_dir_include),
+ "--download",
+ ],
+ capture_output=True,
+ text=True,
+ cwd=parent_dir,
+ )
+ assert result.returncode == 0
+ assert (out_dir_include / "node_modules" / "ms-2.0.0.tgz").is_file()
+ assert (out_dir_include / "node_modules" /
"negotiator-0.6.3.tgz").is_file()