diff --git a/test/mason/publish/dryTest.chpl b/test/mason/publish/dryTest.chpl index 39d73ee51293..7463f13b0145 100644 --- a/test/mason/publish/dryTest.chpl +++ b/test/mason/publish/dryTest.chpl @@ -6,9 +6,9 @@ use MasonNew; const dir = here.cwd(); proc dry() { - masonNew(['mason', 'new', 'publishCheck']); + masonNew(['new', 'publishCheck']); here.chdir(dir + '/publishCheck'); - masonPublish(['mason', 'publish', '--dry-run']); + masonPublish(['publish', '--dry-run']); } -dry(); \ No newline at end of file +dry(); diff --git a/test/mason/publish/dryTest.good b/test/mason/publish/dryTest.good index f5e36745eb9a..4d65669b37e4 100644 --- a/test/mason/publish/dryTest.good +++ b/test/mason/publish/dryTest.good @@ -1,2 +1,2 @@ -Created new library project: publishCheck +Created new application project: publishCheck Package does not gave a git origin diff --git a/test/mason/publish/licenseList.chpl b/test/mason/publish/licenseList.chpl new file mode 100644 index 000000000000..3f79f6aad4d6 --- /dev/null +++ b/test/mason/publish/licenseList.chpl @@ -0,0 +1,12 @@ +use MasonPublish; +use MasonEnv; +use FileSystem; + + +proc main() { + const args = ["publish", "--refresh-licenses"]; + const spdxDir = MASON_HOME + '/spdx'; + const spdxTextDir = spdxDir + "/text"; + if exists(spdxTextDir) then rmTree(spdxTextDir); + masonPublish(args); +} diff --git a/test/mason/publish/licenseList.compopts b/test/mason/publish/licenseList.compopts new file mode 100644 index 000000000000..ddb2a0f3c5a8 --- /dev/null +++ b/test/mason/publish/licenseList.compopts @@ -0,0 +1 @@ +-M ../../../tools/mason diff --git a/test/mason/publish/licenseList.good b/test/mason/publish/licenseList.good new file mode 100644 index 000000000000..f7bc17ec67b9 --- /dev/null +++ b/test/mason/publish/licenseList.good @@ -0,0 +1,2 @@ +Force updating list of valid license names from SPDX repo... +Done updating license list diff --git a/test/mason/publish/licenseRefresh.chpl b/test/mason/publish/licenseRefresh.chpl new file mode 100644 index 000000000000..d11b0168866b --- /dev/null +++ b/test/mason/publish/licenseRefresh.chpl @@ -0,0 +1,37 @@ +use MasonPublish; +use MasonEnv; +use MasonUtils; +use FileSystem; +use Time; + + +proc main() { + const args = ["publish", "--refresh-licenses"]; + const spdxDir = MASON_HOME + '/spdx'; + const spdxTextDir = spdxDir + "/text"; + + // creates a new dir and clones when it doesn't exist, without overwrite flag + if exists(spdxDir) then rmTree(spdxDir); + writeln("spdx dir does not exist, creating it..."); + refreshLicenseList(); + + assert(exists(spdxDir)); + assert(exists(spdxTextDir)); + writeln("spdx dir was created, removing the text/ subdir..."); + rmTree(spdxTextDir); + + assert(!exists(spdxTextDir)); + + + try! { + refreshLicenseList(); // expect this to error because we deleted the text dir + } catch e: MasonError { + assert(!exists(spdxTextDir)); + writeln("spdx/text dir was not recreated because we did not force an overwrite"); + } + + sleep(5); // sleep a little to let git settle from the previous clone above + refreshLicenseList(true); // set the overwrite flag to force getting the repo again + assert(exists(spdxTextDir)); + writeln("spdx/text dir was recreated with use of overwrite flag"); +} diff --git a/test/mason/publish/licenseRefresh.compopts b/test/mason/publish/licenseRefresh.compopts new file mode 100644 index 000000000000..ddb2a0f3c5a8 --- /dev/null +++ b/test/mason/publish/licenseRefresh.compopts @@ -0,0 +1 @@ +-M ../../../tools/mason diff --git a/test/mason/publish/licenseRefresh.good b/test/mason/publish/licenseRefresh.good new file mode 100644 index 000000000000..e6f5779d584a --- /dev/null +++ b/test/mason/publish/licenseRefresh.good @@ -0,0 +1,4 @@ +spdx dir does not exist, creating it... +spdx dir was created, removing the text/ subdir... +spdx/text dir was not recreated because we did not force an overwrite +spdx/text dir was recreated with use of overwrite flag diff --git a/test/mason/publish/publishHelp.good b/test/mason/publish/publishHelp.good index 5ca9e10e6583..c000968adfbe 100644 --- a/test/mason/publish/publishHelp.good +++ b/test/mason/publish/publishHelp.good @@ -10,6 +10,7 @@ Options: --dry-run Check to see if package is ready to be published --check Runs check to see if package can be published successfully to --ci-check Same as --check, except omits git origin checks - --[no-]update [Do not] Prevent registries from being updated when a package is published. + --[no-]update [Do not] Prevent registries from being updated when a package is published + --refresh-licenses Force-update the list of valid license names and immediately exit without publishing Publishing requires the mason-registry to be forked and the package to have a remote origin. diff --git a/test/mason/publish/publishHelpShort.good b/test/mason/publish/publishHelpShort.good index 5ca9e10e6583..c000968adfbe 100644 --- a/test/mason/publish/publishHelpShort.good +++ b/test/mason/publish/publishHelpShort.good @@ -10,6 +10,7 @@ Options: --dry-run Check to see if package is ready to be published --check Runs check to see if package can be published successfully to --ci-check Same as --check, except omits git origin checks - --[no-]update [Do not] Prevent registries from being updated when a package is published. + --[no-]update [Do not] Prevent registries from being updated when a package is published + --refresh-licenses Force-update the list of valid license names and immediately exit without publishing Publishing requires the mason-registry to be forked and the package to have a remote origin. diff --git a/tools/mason/MasonHelp.chpl b/tools/mason/MasonHelp.chpl index 9b0dd4cd4edd..c895e0836b76 100644 --- a/tools/mason/MasonHelp.chpl +++ b/tools/mason/MasonHelp.chpl @@ -589,7 +589,8 @@ proc masonPublishHelp(){ writeln(' --dry-run Check to see if package is ready to be published'); writeln(' --check Runs check to see if package can be published successfully to '); writeln(' --ci-check Same as --check, except omits git origin checks'); - writeln(' --[no-]update [Do not] Prevent registries from being updated when a package is published.'); + writeln(' --[no-]update [Do not] Prevent registries from being updated when a package is published'); + writeln(' --refresh-licenses Force-update the list of valid license names and immediately exit without publishing'); writeln(); writeln('Publishing requires the mason-registry to be forked and the package to have a remote origin.'); } diff --git a/tools/mason/MasonPublish.chpl b/tools/mason/MasonPublish.chpl index b601f8a31df7..a2c91d4ed5df 100644 --- a/tools/mason/MasonPublish.chpl +++ b/tools/mason/MasonPublish.chpl @@ -58,11 +58,15 @@ proc masonPublish(ref args: list(string)) throws { var updateFlag = parser.addFlag(name="update", flagInversion=true); var registryArg = parser.addArgument(name="registry", numArgs=0..1); + var refreshLicenseFlag = parser.addFlag(name="refresh-licenses", + defaultValue=false); + parser.parseArgs(args.toArray()); try! { var dry = dryFlag.valueAsBool(); var checkFlag = checkArg.valueAsBool(); + var refreshLicenses = refreshLicenseFlag.valueAsBool(); var registryPath = ""; if registryArg.hasValue() then registryPath = registryArg.value(); var username = getUsername(); @@ -78,7 +82,14 @@ proc masonPublish(ref args: list(string)) throws { } var createReg = createFlag.valueAsBool(); - const badSyntaxMessage = 'Arguments does not follow "mason publish [options] " syntax'; + const badSyntaxMessage = 'Arguments do not follow "mason publish [options] " syntax'; + + if refreshLicenses { + writeln("Force updating list of valid license names from SPDX repo..."); + refreshLicenseList(true); + writeln("Done updating license list"); + exit(0); + } if createReg { var pathReg = registryPath; @@ -669,6 +680,34 @@ proc check(username : string, path : string, trueIfLocal : bool, ci : bool) thro exit(0); } +/* + update the list of valid licenses or pulls a new copy of the list if one + does not already exist. If overwrite is true, delete the list and pull a new + copy of the repo. +*/ +proc refreshLicenseList(overwrite=false) throws { + const dest = MASON_HOME + '/spdx'; + const branch = '--branch main '; + const depth = '--depth 1 '; + const url = 'https://github.com/spdx/license-list-data.git '; + const command = 'git clone -q ' + branch + depth + url + dest; + if !isDir(dest) { + runCommand(command); + } else if overwrite { + rmTree(dest); + runCommand(command); + } + + if !isDir(dest + "/text") { + throw new owned MasonError("Expected to find license list data at " + dest + + "/text, but location does not exist. Try running\ + 'mason publish --refresh-licenses' to update the\ + license list."); + } + const licenseList = listDir(dest + "/text"); + return licenseList; +} + /* Validate license with that of SPDX list */ private proc checkLicense(projectHome: string) throws { var foundValidLicense = false; @@ -679,14 +718,8 @@ private proc checkLicense(projectHome: string) throws { if tomlFile.pathExists("brick.license") { defaultLicense = tomlFile["brick"]!["license"]!.s; } - // git clone the SPDX repo and validate license identifier - const dest = MASON_HOME + '/spdx'; - const branch = '--branch master '; - const depth = '--depth 1 '; - const url = 'https://github.com/spdx/license-list.git '; - const command = 'git clone -q ' + branch + depth + url + dest; - if !isDir(dest) then runCommand(command); - var licenseList = listDir(MASON_HOME + "/spdx"); + // get the license list and validate license identifier + const licenseList = refreshLicenseList(); for licenses in licenseList { const licenseName: string = licenses.strip('.txt', trailing=true); if licenseName == defaultLicense || defaultLicense == 'None' { @@ -705,7 +738,7 @@ private proc attemptToBuild() throws { var sub = spawn(['mason','build','--force'], stdout=pipeStyle.pipe); sub.wait(); if sub.exitCode == 1 { - writeln('(FAILED) Please make sure your package builds'); + writeln('(FAILED) Please make sure your package builds'); } else { writeln('(PASSED) Package builds successfully.'); @@ -820,7 +853,7 @@ private proc returnMasonEnv() { private proc falseIfRemotePath() { var registryInEnv = MASON_REGISTRY; - for (name, registry) in registryInEnv { + for (_, registry) in registryInEnv { if registry.find(':') != -1 { return false; }