diff --git a/.github/workflows/dependabot-auto-fix.yml b/.github/workflows/dependabot-auto-fix.yml new file mode 100644 index 0000000..7360ef6 --- /dev/null +++ b/.github/workflows/dependabot-auto-fix.yml @@ -0,0 +1,41 @@ +name: Dependabot Auto Fix and Merge + +on: + pull_request: + types: [opened, synchronize, reopened] + +permissions: + contents: write + pull-requests: write + +jobs: + dependabot-auto-fix: + runs-on: ubuntu-latest + if: github.actor == 'dependabot[bot]' + steps: + - uses: actions/checkout@v4 + with: + ref: ${{ github.head_ref }} + token: ${{ secrets.GITHUB_TOKEN }} + + - uses: actions/setup-node@v4 + + - run: yarn install --no-immutable + env: + WORKSPACE_LOCKFILE_FORCE_WRITE: true + + - name: Commit and push changes if any + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + if ! git diff --quiet; then + git add -A + git commit -m "update lockfiles after yarn install [auto-fix]" + git push + fi + + - name: Enable auto-merge for Dependabot PRs + run: gh pr merge --auto --squash "$PR_URL" + env: + PR_URL: ${{ github.event.pull_request.html_url }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/README.md b/README.md index 1e30891..20512e9 100644 --- a/README.md +++ b/README.md @@ -119,14 +119,19 @@ Both files use the same format for common fields: - Non-scoped packages are not quoted: `fastq: "npm:^1.6.0"` - Alphabetical ordering of packages and their dependencies -### Missing Metadata (Potential Future Additions) -The following fields from `yarn.lock` are currently not included in `yarn.workspace.lock`: -- `checksum`: Package integrity checksums -- `languageName`: The language of the package (e.g., "node") -- `linkType`: How the package should be linked (e.g., "hard") -- `__metadata`: Top-level metadata about the lockfile itself (e.g., version, cacheKey) - -These metadata fields could be added in future versions if they prove useful for workspace-specific use cases. +## Environment Variables + +### `WORKSPACE_LOCKFILE_FORCE_WRITE` + +If set to `true`, this environment variable will force the plugin to write workspace lockfiles even when Yarn is run with the `--immutable` flag. This is useful in CI or automation scenarios where you want to ensure lockfiles are always updated, regardless of the immutable setting. + +**Example:** + +```sh +WORKSPACE_LOCKFILE_FORCE_WRITE=true yarn install --immutable +``` + +This will override the immutable check and update the `yarn.workspace.lock` files as needed. ## Publishing diff --git a/bundles/@yarnpkg/plugin-workspace-lockfile.js b/bundles/@yarnpkg/plugin-workspace-lockfile.js index 40897c4..5de2f75 100644 --- a/bundles/@yarnpkg/plugin-workspace-lockfile.js +++ b/bundles/@yarnpkg/plugin-workspace-lockfile.js @@ -3,11 +3,11 @@ module.exports = { name: "@yarnpkg/plugin-workspace-lockfile", factory: function (require) { -"use strict";var plugin=(()=>{var F=Object.create;var P=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty;var O=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(s,n)=>(typeof require<"u"?require:s)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var h=(e,s)=>()=>(s||e((s={exports:{}}).exports,s),s.exports),q=(e,s)=>{for(var n in s)P(e,n,{get:s[n],enumerable:!0})},B=(e,s,n,i)=>{if(s&&typeof s=="object"||typeof s=="function")for(let g of Q(s))!Y.call(e,g)&&g!==n&&P(e,g,{get:()=>s[g],enumerable:!(i=H(s,g))||i.enumerable});return e};var z=(e,s,n)=>(n=e!=null?F(K(e)):{},B(s||!e||!e.__esModule?P(n,"default",{value:e,enumerable:!0}):n,e)),X=e=>B(P({},"__esModule",{value:!0}),e);var M=h((re,x)=>{x.exports=[{name:"Agola CI",constant:"AGOLA",env:"AGOLA_GIT_REF",pr:"AGOLA_PULL_REQUEST_ID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE",pr:{env:"AC_GIT_PR",ne:"false"}},{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN",pr:{env:"CODEBUILD_WEBHOOK_EVENT",any:["PULL_REQUEST_CREATED","PULL_REQUEST_UPDATED","PULL_REQUEST_REOPENED"]}},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"TF_BUILD",pr:{BUILD_REASON:"PullRequest"}},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"Cloudflare Pages",constant:"CLOUDFLARE_PAGES",env:"CF_PAGES"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codemagic",constant:"CODEMAGIC",env:"CM_BUILD_ID",pr:"CM_PULL_REQUEST"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"Earthly",constant:"EARTHLY",env:"EARTHLY_CI"},{name:"Expo Application Services",constant:"EAS",env:"EAS_BUILD"},{name:"Gerrit",constant:"GERRIT",env:"GERRIT_PROJECT"},{name:"Gitea Actions",constant:"GITEA_ACTIONS",env:"GITEA_ACTIONS"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Google Cloud Build",constant:"GOOGLE_CLOUD_BUILD",env:"BUILDER_OUTPUT"},{name:"Harness CI",constant:"HARNESS",env:"HARNESS_BUILD_ID"},{name:"Heroku",constant:"HEROKU",env:{env:"NODE",includes:"/app/.heroku/node/bin/node"}},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Prow",constant:"PROW",env:"PROW_JOB_ID"},{name:"ReleaseHub",constant:"RELEASEHUB",env:"RELEASE_BUILD_ID"},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Sourcehut",constant:"SOURCEHUT",env:{CI_NAME:"sourcehut"}},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vela",constant:"VELA",env:"VELA",pr:{VELA_PULL_REQUEST:"1"}},{name:"Vercel",constant:"VERCEL",env:{any:["NOW_BUILDER","VERCEL"]},pr:"VERCEL_GIT_PULL_REQUEST_ID"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"},{name:"Woodpecker",constant:"WOODPECKER",env:{CI:"woodpecker"},pr:{CI_BUILD_EVENT:"pull_request"}},{name:"Xcode Cloud",constant:"XCODE_CLOUD",env:"CI_XCODE_PROJECT",pr:"CI_PULL_REQUEST_NUMBER"},{name:"Xcode Server",constant:"XCODE_SERVER",env:"XCS"}]});var b=h(_=>{"use strict";var $=M(),p=process.env;Object.defineProperty(_,"_vendors",{value:$.map(function(e){return e.constant})});_.name=null;_.isPR=null;_.id=null;$.forEach(function(e){let n=(Array.isArray(e.env)?e.env:[e.env]).every(function(i){return W(i)});_[e.constant]=n,n&&(_.name=e.name,_.isPR=J(e),_.id=e.constant)});_.isCI=!!(p.CI!=="false"&&(p.BUILD_ID||p.BUILD_NUMBER||p.CI||p.CI_APP_ID||p.CI_BUILD_ID||p.CI_BUILD_NUMBER||p.CI_NAME||p.CONTINUOUS_INTEGRATION||p.RUN_ID||_.name));function W(e){return typeof e=="string"?!!p[e]:"env"in e?p[e.env]&&p[e.env].includes(e.includes):"any"in e?e.any.some(function(s){return!!p[s]}):Object.keys(e).every(function(s){return p[s]===e[s]})}function J(e){switch(typeof e.pr){case"string":return!!p[e.pr];case"object":return"env"in e.pr?"any"in e.pr?e.pr.any.some(function(s){return p[e.pr.env]===s}):e.pr.env in p&&p[e.pr.env]!==e.pr.ne:"any"in e.pr?e.pr.any.some(function(s){return!!p[s]}):W(e.pr);default:return null}}});var se={};q(se,{default:()=>ne});var t=O("@yarnpkg/core"),k=O("@yarnpkg/fslib"),V=z(b());async function Z(e,s,n,{report:i,immutable:g,cache:y,persistProject:A}){try{let m=new Set,U=s.manifest;for(let d of["dependencies","devDependencies","peerDependencies"]){let c=U.getForScope(d);n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Found ${c.size} ${d}`);for(let r of c.values()){let I=n.workspaces.find(u=>u.manifest.raw.name===r.name||u.manifest.raw.name===`@${r.scope}/${r.name}`);if(I){let u=t.structUtils.makeDescriptor(t.structUtils.makeIdent(r.scope||"",r.name),r.range);m.add(u),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added workspace dependency: ${t.structUtils.stringifyDescriptor(u)}`);for(let l of["dependencies","devDependencies","peerDependencies"]){let E=I.manifest.getForScope(l);for(let f of E.values()){let o=t.structUtils.makeDescriptor(t.structUtils.makeIdent(f.scope||"npm",f.name),f.range);m.add(o),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added transitive dependency from workspace: ${t.structUtils.stringifyDescriptor(o)}`)}}}else{let u=r.scope?`@${r.scope}/${r.name}`:r.name,l=t.structUtils.parseIdent(u),f=r.range.match(/^([a-z]+):/)?.[1]?r.range:`npm:${r.range}`,o=t.structUtils.makeDescriptor(l,f);m.add(o),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added dependency: ${t.structUtils.stringifyDescriptor(o)}`)}}}let L=new Map,S=new Set,a=new Map,D=d=>{let c=t.structUtils.parseDescriptor(d);return c.range.startsWith("workspace:")?t.structUtils.stringifyDescriptor(c):t.structUtils.stringifyDescriptor(t.structUtils.makeDescriptor(c,`npm:${c.range.replace(/^npm:/,"")}`))},C=d=>{let c=t.structUtils.stringifyDescriptor(d),r=D(c);if(S.has(r))return;let I=n.storedResolutions.get(d.descriptorHash);if(!I){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`No resolution found for ${c}`);return}a.has(I)||a.set(I,new Set),a.get(I).add(d);let u=n.storedPackages.get(I);if(!u){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`No package found for ${c}`);return}S.add(r);for(let[l,E]of u.dependencies)C(E);for(let[l,E]of u.peerDependencies)C(E)};for(let d of m)C(d);for(let[d,c]of a){let r=n.storedPackages.get(d);if(!r)continue;let I=Array.from(c).map(f=>t.structUtils.stringifyDescriptor(f)).filter(f=>!f.includes("virtual:")).sort();if(I.length===0)continue;let u=I.join(", "),l=new Map,E=new Map;for(let[f,o]of r.dependencies){let R=o.range.startsWith("virtual:")?`npm:${o.range.replace(/^virtual:[^#]+#npm:/,"")}`:o.range.startsWith("workspace:")||o.range.startsWith("npm:")?o.range:`npm:${o.range}`;l.set(t.structUtils.stringifyIdent(o),R)}for(let[f,o]of r.peerDependencies){let R=t.structUtils.stringifyIdent(o),w=o.range.startsWith("virtual:")?`npm:${o.range.replace(/^virtual:[^#]+#npm:/,"")}`:o.range.startsWith("workspace:")||o.range.startsWith("npm:")?o.range:`npm:${o.range}`;if(R.startsWith("@types/")&&r.peerDependenciesMeta.get(R)?.optional&&o.range==="*"){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Skipping optional @types peer dependency: ${R}@${w}`);continue}E.set(R,w)}L.set(u,{version:r.linkType===t.LinkType.SOFT&&r.reference.startsWith("workspace:")?"0.0.0-use.local":r.version,resolution:t.structUtils.stringifyLocator(r),dependencies:l,peerDependencies:E,bin:r.bin,checksum:n.storedChecksums.get(d)||"",languageName:r.languageName,linkType:r.linkType})}n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Generated ${L.size} entries for workspace lockfile`);let T=Array.from(L.entries()).sort().map(([d,c])=>{let r=c.dependencies.size>0?` dependencies: +"use strict";var plugin=(()=>{var F=Object.create;var P=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,Y=Object.prototype.hasOwnProperty;var w=(e=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(e,{get:(s,n)=>(typeof require<"u"?require:s)[n]}):e)(function(e){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+e+'" is not supported')});var h=(e,s)=>()=>(s||e((s={exports:{}}).exports,s),s.exports),q=(e,s)=>{for(var n in s)P(e,n,{get:s[n],enumerable:!0})},B=(e,s,n,i)=>{if(s&&typeof s=="object"||typeof s=="function")for(let I of K(s))!Y.call(e,I)&&I!==n&&P(e,I,{get:()=>s[I],enumerable:!(i=H(s,I))||i.enumerable});return e};var z=(e,s,n)=>(n=e!=null?F(Q(e)):{},B(s||!e||!e.__esModule?P(n,"default",{value:e,enumerable:!0}):n,e)),X=e=>B(P({},"__esModule",{value:!0}),e);var M=h((oe,x)=>{x.exports=[{name:"Agola CI",constant:"AGOLA",env:"AGOLA_GIT_REF",pr:"AGOLA_PULL_REQUEST_ID"},{name:"Appcircle",constant:"APPCIRCLE",env:"AC_APPCIRCLE",pr:{env:"AC_GIT_PR",ne:"false"}},{name:"AppVeyor",constant:"APPVEYOR",env:"APPVEYOR",pr:"APPVEYOR_PULL_REQUEST_NUMBER"},{name:"AWS CodeBuild",constant:"CODEBUILD",env:"CODEBUILD_BUILD_ARN",pr:{env:"CODEBUILD_WEBHOOK_EVENT",any:["PULL_REQUEST_CREATED","PULL_REQUEST_UPDATED","PULL_REQUEST_REOPENED"]}},{name:"Azure Pipelines",constant:"AZURE_PIPELINES",env:"TF_BUILD",pr:{BUILD_REASON:"PullRequest"}},{name:"Bamboo",constant:"BAMBOO",env:"bamboo_planKey"},{name:"Bitbucket Pipelines",constant:"BITBUCKET",env:"BITBUCKET_COMMIT",pr:"BITBUCKET_PR_ID"},{name:"Bitrise",constant:"BITRISE",env:"BITRISE_IO",pr:"BITRISE_PULL_REQUEST"},{name:"Buddy",constant:"BUDDY",env:"BUDDY_WORKSPACE_ID",pr:"BUDDY_EXECUTION_PULL_REQUEST_ID"},{name:"Buildkite",constant:"BUILDKITE",env:"BUILDKITE",pr:{env:"BUILDKITE_PULL_REQUEST",ne:"false"}},{name:"CircleCI",constant:"CIRCLE",env:"CIRCLECI",pr:"CIRCLE_PULL_REQUEST"},{name:"Cirrus CI",constant:"CIRRUS",env:"CIRRUS_CI",pr:"CIRRUS_PR"},{name:"Cloudflare Pages",constant:"CLOUDFLARE_PAGES",env:"CF_PAGES"},{name:"Codefresh",constant:"CODEFRESH",env:"CF_BUILD_ID",pr:{any:["CF_PULL_REQUEST_NUMBER","CF_PULL_REQUEST_ID"]}},{name:"Codemagic",constant:"CODEMAGIC",env:"CM_BUILD_ID",pr:"CM_PULL_REQUEST"},{name:"Codeship",constant:"CODESHIP",env:{CI_NAME:"codeship"}},{name:"Drone",constant:"DRONE",env:"DRONE",pr:{DRONE_BUILD_EVENT:"pull_request"}},{name:"dsari",constant:"DSARI",env:"DSARI"},{name:"Earthly",constant:"EARTHLY",env:"EARTHLY_CI"},{name:"Expo Application Services",constant:"EAS",env:"EAS_BUILD"},{name:"Gerrit",constant:"GERRIT",env:"GERRIT_PROJECT"},{name:"Gitea Actions",constant:"GITEA_ACTIONS",env:"GITEA_ACTIONS"},{name:"GitHub Actions",constant:"GITHUB_ACTIONS",env:"GITHUB_ACTIONS",pr:{GITHUB_EVENT_NAME:"pull_request"}},{name:"GitLab CI",constant:"GITLAB",env:"GITLAB_CI",pr:"CI_MERGE_REQUEST_ID"},{name:"GoCD",constant:"GOCD",env:"GO_PIPELINE_LABEL"},{name:"Google Cloud Build",constant:"GOOGLE_CLOUD_BUILD",env:"BUILDER_OUTPUT"},{name:"Harness CI",constant:"HARNESS",env:"HARNESS_BUILD_ID"},{name:"Heroku",constant:"HEROKU",env:{env:"NODE",includes:"/app/.heroku/node/bin/node"}},{name:"Hudson",constant:"HUDSON",env:"HUDSON_URL"},{name:"Jenkins",constant:"JENKINS",env:["JENKINS_URL","BUILD_ID"],pr:{any:["ghprbPullId","CHANGE_ID"]}},{name:"LayerCI",constant:"LAYERCI",env:"LAYERCI",pr:"LAYERCI_PULL_REQUEST"},{name:"Magnum CI",constant:"MAGNUM",env:"MAGNUM"},{name:"Netlify CI",constant:"NETLIFY",env:"NETLIFY",pr:{env:"PULL_REQUEST",ne:"false"}},{name:"Nevercode",constant:"NEVERCODE",env:"NEVERCODE",pr:{env:"NEVERCODE_PULL_REQUEST",ne:"false"}},{name:"Prow",constant:"PROW",env:"PROW_JOB_ID"},{name:"ReleaseHub",constant:"RELEASEHUB",env:"RELEASE_BUILD_ID"},{name:"Render",constant:"RENDER",env:"RENDER",pr:{IS_PULL_REQUEST:"true"}},{name:"Sail CI",constant:"SAIL",env:"SAILCI",pr:"SAIL_PULL_REQUEST_NUMBER"},{name:"Screwdriver",constant:"SCREWDRIVER",env:"SCREWDRIVER",pr:{env:"SD_PULL_REQUEST",ne:"false"}},{name:"Semaphore",constant:"SEMAPHORE",env:"SEMAPHORE",pr:"PULL_REQUEST_NUMBER"},{name:"Sourcehut",constant:"SOURCEHUT",env:{CI_NAME:"sourcehut"}},{name:"Strider CD",constant:"STRIDER",env:"STRIDER"},{name:"TaskCluster",constant:"TASKCLUSTER",env:["TASK_ID","RUN_ID"]},{name:"TeamCity",constant:"TEAMCITY",env:"TEAMCITY_VERSION"},{name:"Travis CI",constant:"TRAVIS",env:"TRAVIS",pr:{env:"TRAVIS_PULL_REQUEST",ne:"false"}},{name:"Vela",constant:"VELA",env:"VELA",pr:{VELA_PULL_REQUEST:"1"}},{name:"Vercel",constant:"VERCEL",env:{any:["NOW_BUILDER","VERCEL"]},pr:"VERCEL_GIT_PULL_REQUEST_ID"},{name:"Visual Studio App Center",constant:"APPCENTER",env:"APPCENTER_BUILD_ID"},{name:"Woodpecker",constant:"WOODPECKER",env:{CI:"woodpecker"},pr:{CI_BUILD_EVENT:"pull_request"}},{name:"Xcode Cloud",constant:"XCODE_CLOUD",env:"CI_XCODE_PROJECT",pr:"CI_PULL_REQUEST_NUMBER"},{name:"Xcode Server",constant:"XCODE_SERVER",env:"XCS"}]});var b=h(_=>{"use strict";var W=M(),p=process.env;Object.defineProperty(_,"_vendors",{value:W.map(function(e){return e.constant})});_.name=null;_.isPR=null;_.id=null;W.forEach(function(e){let n=(Array.isArray(e.env)?e.env:[e.env]).every(function(i){return $(i)});_[e.constant]=n,n&&(_.name=e.name,_.isPR=J(e),_.id=e.constant)});_.isCI=!!(p.CI!=="false"&&(p.BUILD_ID||p.BUILD_NUMBER||p.CI||p.CI_APP_ID||p.CI_BUILD_ID||p.CI_BUILD_NUMBER||p.CI_NAME||p.CONTINUOUS_INTEGRATION||p.RUN_ID||_.name));function $(e){return typeof e=="string"?!!p[e]:"env"in e?p[e.env]&&p[e.env].includes(e.includes):"any"in e?e.any.some(function(s){return!!p[s]}):Object.keys(e).every(function(s){return p[s]===e[s]})}function J(e){switch(typeof e.pr){case"string":return!!p[e.pr];case"object":return"env"in e.pr?"any"in e.pr?e.pr.any.some(function(s){return p[e.pr.env]===s}):e.pr.env in p&&p[e.pr.env]!==e.pr.ne:"any"in e.pr?e.pr.any.some(function(s){return!!p[s]}):$(e.pr);default:return null}}});var se={};q(se,{default:()=>ne});var t=w("@yarnpkg/core"),k=w("@yarnpkg/fslib"),V=z(b());async function Z(e,s,n,{report:i,immutable:I,cache:y,persistProject:A}){try{let m=new Set,U=s.manifest;for(let u of["dependencies","devDependencies","peerDependencies"]){let c=U.getForScope(u);n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Found ${c.size} ${u}`);for(let r of c.values()){let g=n.workspaces.find(d=>d.manifest.raw.name===r.name||d.manifest.raw.name===`@${r.scope}/${r.name}`);if(g){let d=t.structUtils.makeDescriptor(t.structUtils.makeIdent(r.scope||"",r.name),r.range);m.add(d),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added workspace dependency: ${t.structUtils.stringifyDescriptor(d)}`);for(let l of["dependencies","devDependencies","peerDependencies"]){let E=g.manifest.getForScope(l);for(let f of E.values()){let o=t.structUtils.makeDescriptor(t.structUtils.makeIdent(f.scope||"npm",f.name),f.range);m.add(o),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added transitive dependency from workspace: ${t.structUtils.stringifyDescriptor(o)}`)}}}else{let d=r.scope?`@${r.scope}/${r.name}`:r.name,l=t.structUtils.parseIdent(d),f=r.range.match(/^([a-z]+):/)?.[1]?r.range:`npm:${r.range}`,o=t.structUtils.makeDescriptor(l,f);m.add(o),n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Added dependency: ${t.structUtils.stringifyDescriptor(o)}`)}}}let L=new Map,S=new Set,a=new Map,D=u=>{let c=t.structUtils.parseDescriptor(u);return c.range.startsWith("workspace:")?t.structUtils.stringifyDescriptor(c):t.structUtils.stringifyDescriptor(t.structUtils.makeDescriptor(c,`npm:${c.range.replace(/^npm:/,"")}`))},C=u=>{let c=t.structUtils.stringifyDescriptor(u),r=D(c);if(S.has(r))return;let g=n.storedResolutions.get(u.descriptorHash);if(!g){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`No resolution found for ${c}`);return}a.has(g)||a.set(g,new Set),a.get(g).add(u);let d=n.storedPackages.get(g);if(!d){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`No package found for ${c}`);return}S.add(r);for(let[l,E]of d.dependencies)C(E);for(let[l,E]of d.peerDependencies)C(E)};for(let u of m)C(u);for(let[u,c]of a){let r=n.storedPackages.get(u);if(!r)continue;let g=Array.from(c).map(f=>t.structUtils.stringifyDescriptor(f)).filter(f=>!f.includes("virtual:")).sort();if(g.length===0)continue;let d=g.join(", "),l=new Map,E=new Map;for(let[f,o]of r.dependencies){let R=o.range.startsWith("virtual:")?`npm:${o.range.replace(/^virtual:[^#]+#npm:/,"")}`:o.range.startsWith("workspace:")||o.range.startsWith("npm:")?o.range:`npm:${o.range}`;l.set(t.structUtils.stringifyIdent(o),R)}for(let[f,o]of r.peerDependencies){let R=t.structUtils.stringifyIdent(o),O=o.range.startsWith("virtual:")?`npm:${o.range.replace(/^virtual:[^#]+#npm:/,"")}`:o.range.startsWith("workspace:")||o.range.startsWith("npm:")?o.range:`npm:${o.range}`;if(R.startsWith("@types/")&&r.peerDependenciesMeta.get(R)?.optional&&o.range==="*"){n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Skipping optional @types peer dependency: ${R}@${O}`);continue}E.set(R,O)}L.set(d,{version:r.linkType===t.LinkType.SOFT&&r.reference.startsWith("workspace:")?"0.0.0-use.local":r.version,resolution:t.structUtils.stringifyLocator(r),dependencies:l,peerDependencies:E,bin:r.bin,checksum:n.storedChecksums.get(u)||"",languageName:r.languageName,linkType:r.linkType})}n.configuration.get("enableVerboseLogging")&&i.reportInfo(t.MessageName.UNNAMED,`Generated ${L.size} entries for workspace lockfile`);let T=Array.from(L.entries()).sort().map(([u,c])=>{let r=c.dependencies.size>0?` dependencies: ${Array.from(c.dependencies.entries()).sort().map(([l,E])=>{let f=E.startsWith("workspace:")?E:`npm:${E.replace(/^npm:/,"")}`;return` ${l.startsWith("@")?`"${l}"`:l}: "${f}"`}).join(` -`)}`:"",I=c.peerDependencies.size>0?` peerDependencies: +`)}`:"",g=c.peerDependencies.size>0?` peerDependencies: ${Array.from(c.peerDependencies.entries()).sort().map(([l,E])=>{let f=E.startsWith("workspace:")?E:`${E.replace(/^npm:/,"")}`,o=f.match(/[:\{\}\[\]\,&*#?<>=!%@\\]/)?`"${f}"`:f;return` ${l.startsWith("@")?`"${l}"`:l}: ${o}`}).join(` -`)}`:"";return[`"${d}":`,` version: ${c.version||"unknown"}`,` resolution: "${c.resolution}"`,r,I,c.bin.size>0?` bin: +`)}`:"";return[`"${u}":`,` version: ${c.version||"unknown"}`,` resolution: "${c.resolution}"`,r,g,c.bin.size>0?` bin: ${Array.from(c.bin.entries()).map(([l,E])=>` ${l}: ${E}`).join(` `)}`:"",` checksum: ${c.checksum}`,` languageName: ${c.languageName.toLowerCase()}`,` linkType: ${c.linkType.toLowerCase()}`].filter(Boolean).join(` `)+` @@ -19,7 +19,7 @@ __metadata: version: ${n.lockfileLastVersion??"6"} cacheKey: ${G} -${T}`,N=k.ppath.join(s.cwd,"yarn.workspace.lock");if(g){if(await k.xfs.readFilePromise(N,"utf-8")===v)return;i.reportError(t.MessageName.UNNAMED,`The lockfile ${N} would have been modified by this install, which is explicitly forbidden`)}else await k.xfs.writeFilePromise(N,v),i.reportInfo(t.MessageName.UNNAMED,`Created ${N}`)}catch(m){let U=m instanceof Error?m.message:String(m);i.reportError(t.MessageName.UNNAMED,`Failed to generate lockfile for ${e}: ${U}`)}}function j(e,s){if(s.persistProject!==!1)return{isWorkspaceFocused:!1};let n=process.argv.slice(2),i=n[0]==="workspaces"&&n[1]==="focus",g=i&&n.some(a=>a==="--production"),y=i&&n.some(a=>a==="--all"||a==="-A");if(!i)return{isWorkspaceFocused:!1};if(y)return{isWorkspaceFocused:!0,isProduction:g,workspaces:e.workspaces};let A=n.slice(2).filter(a=>!a.startsWith("-"));if(A.length===0){let a=k.ppath.cwd(),D=e.workspacesByCwd.get(a);if(!D)throw new Error(`No workspace found in ${a}, please specify a workspace or use --all or -A`);A.push(D.manifest.raw.name)}let m=new Map(e.workspaces.map(a=>[a.manifest.raw.name,a])),U=new Set(A),L=new Set;function S(a){if(!L.has(a)){L.add(a),U.add(a.manifest.raw.name);for(let[D,C]of new Map([...a.manifest.getForScope("dependencies").entries(),...a.manifest.getForScope("devDependencies").entries()]))if(C.range.startsWith("workspace:")){let T=m.get(C.name);T&&S(T)}}}for(let a of U){let D=m.get(a);if(D)S(D);else throw new Error(`Workspace ${a} not found in the project`)}return{isWorkspaceFocused:i,isProduction:g,workspaces:Array.from(L)}}var ee={configuration:{enableVerboseLogging:{description:"If true, enables verbose logging for workspace lockfile generation",type:t.SettingsType.BOOLEAN,default:!1}},hooks:{async afterAllInstalled(e,s){let n=j(e,s);n.isWorkspaceFocused&&(n.isProduction||!n.workspaces?.length)||(n.isWorkspaceFocused&&V.isCI&&(s.immutable=!0),await s.report.startTimerPromise("Workspace lockfiles step",async()=>{for(let i of n.workspaces??e.workspaces){let g=i.manifest.raw.name||i.cwd;await s.report.startTimerPromise(`Generating lockfile for ${g}`,async()=>{await Z(g,i,e,s)})}}))}}},ne=ee;return X(se);})(); +${T}`,N=k.ppath.join(s.cwd,"yarn.workspace.lock");if(process.env.WORKSPACE_LOCKFILE_FORCE_WRITE!=="true"&&I){if(await k.xfs.readFilePromise(N,"utf-8")===v)return;i.reportError(t.MessageName.UNNAMED,`The lockfile ${N} would have been modified by this install, which is explicitly forbidden`)}else await k.xfs.writeFilePromise(N,v),i.reportInfo(t.MessageName.UNNAMED,`Created ${N}`)}catch(m){let U=m instanceof Error?m.message:String(m);i.reportError(t.MessageName.UNNAMED,`Failed to generate lockfile for ${e}: ${U}`)}}function j(e,s){if(s.persistProject!==!1)return{isWorkspaceFocused:!1};let n=process.argv.slice(2),i=n[0]==="workspaces"&&n[1]==="focus",I=i&&n.some(a=>a==="--production"),y=i&&n.some(a=>a==="--all"||a==="-A");if(!i)return{isWorkspaceFocused:!1};if(y)return{isWorkspaceFocused:!0,isProduction:I,workspaces:e.workspaces};let A=n.slice(2).filter(a=>!a.startsWith("-"));if(A.length===0){let a=k.ppath.cwd(),D=e.workspacesByCwd.get(a);if(!D)throw new Error(`No workspace found in ${a}, please specify a workspace or use --all or -A`);A.push(D.manifest.raw.name)}let m=new Map(e.workspaces.map(a=>[a.manifest.raw.name,a])),U=new Set(A),L=new Set;function S(a){if(!L.has(a)){L.add(a),U.add(a.manifest.raw.name);for(let[D,C]of new Map([...a.manifest.getForScope("dependencies").entries(),...a.manifest.getForScope("devDependencies").entries()]))if(C.range.startsWith("workspace:")){let T=m.get(C.name);T&&S(T)}}}for(let a of U){let D=m.get(a);if(D)S(D);else throw new Error(`Workspace ${a} not found in the project`)}return{isWorkspaceFocused:i,isProduction:I,workspaces:Array.from(L)}}var ee={configuration:{enableVerboseLogging:{description:"If true, enables verbose logging for workspace lockfile generation",type:t.SettingsType.BOOLEAN,default:!1}},hooks:{async afterAllInstalled(e,s){let n=j(e,s);n.isWorkspaceFocused&&(n.isProduction||!n.workspaces?.length)||(n.isWorkspaceFocused&&V.isCI&&(s.immutable=!0),await s.report.startTimerPromise("Workspace lockfiles step",async()=>{for(let i of n.workspaces??e.workspaces){let I=i.manifest.raw.name||i.cwd;await s.report.startTimerPromise(`Generating lockfile for ${I}`,async()=>{await Z(I,i,e,s)})}}))}}},ne=ee;return X(se);})(); return plugin; } }; diff --git a/src/index.ts b/src/index.ts index 5614c8d..9823e16 100644 --- a/src/index.ts +++ b/src/index.ts @@ -294,7 +294,8 @@ ${lockfilePackages}`; // Write the workspace lockfile const workspaceLockfilePath = ppath.join(workspace.cwd, "yarn.workspace.lock"); - if (immutable) { + const isImmutable = process.env.WORKSPACE_LOCKFILE_FORCE_WRITE !== "true" && immutable; + if (isImmutable) { const existingLockfile = await xfs.readFilePromise(workspaceLockfilePath, "utf-8"); if (existingLockfile === lockfileContent) { return;