diff --git a/CHANGELOG.md b/CHANGELOG.md index ff574f5..4fd584a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,12 @@ All notable changes to this project will be documented in this file. This projec Nothing yet. +## [2.3.2] - TBD + +### Fixed + +- Resolved an issue with Sparkle feed parsing that could cause Recipe Robot to insert a static download URL in URLDownloader if the feed provided a version at the item level instead of the enclosure level (#206). + ## [2.3.1] - 2023-10-19 ### Fixed @@ -410,7 +416,8 @@ Nothing yet. - Initial public release of Recipe Robot (beta). -[Unreleased]: https://github.com/homebysix/recipe-robot/compare/v2.3.1...HEAD +[Unreleased]: https://github.com/homebysix/recipe-robot/compare/v2.3.2...HEAD +[2.3.2]: https://github.com/homebysix/recipe-robot/compare/v2.3.1...v2.3.2 [2.3.1]: https://github.com/homebysix/recipe-robot/compare/v2.3.0...v2.3.1 [2.3.0]: https://github.com/homebysix/recipe-robot/compare/v2.2.0...v2.3.0 [2.2.0]: https://github.com/homebysix/recipe-robot/compare/v2.1.0...v2.2.0 diff --git a/DEVNOTES.md b/DEVNOTES.md index 67c1ab5..5dfcf13 100644 --- a/DEVNOTES.md +++ b/DEVNOTES.md @@ -4,9 +4,11 @@ Some scattered notes to assist in the design and development of Recipe Robot. -- [Facts](#facts) -- [Interesting examples and edge cases to use for testing:](#interesting-examples-and-edge-cases-to-use-for-testing) -- [Content Types](#content-types) +- [Recipe Robot Development Notes](#recipe-robot-development-notes) + - [Facts](#facts) + - [Interesting examples and edge cases to use for testing:](#interesting-examples-and-edge-cases-to-use-for-testing) + - [Content Types](#content-types) + - [Sparkle feeds](#sparkle-feeds) @@ -227,21 +229,70 @@ recipe-robot --verbose https://bahoom.com/hyperdock/HyperDock.dmg To get an grasp of the typical content types that Recipe Robot will be dealing with, I ran `curl -sIL` on every SPARKLE_FEED_URL and DOWNLOAD_URL in the homebysix-recipes repo. Here are the content types that were returned: -| Type | Count | -| ----------------------------------- | ----- | -| text/html | 101 | -| application/xml | 62 | -| application/zip | 33 | -| application/x-apple-diskimage | 24 | -| text/xml | 24 | -| application/octet-stream | 22 | -| text/plain | 7 | -| application/xhtml+xml | 5 | -| application/rss+xml | 3 | -| binary/octet-stream | 3 | -| application/vnd.apple.installer+xml | 1 | -| application/x-bzip2 | 1 | -| application/x-rss+xml | 1 | -| plain/text | 1 | +| Type | Count | +| ----------------------------------- | ----- | +| text/html | 101 | +| application/xml | 62 | +| application/zip | 33 | +| application/x-apple-diskimage | 24 | +| text/xml | 24 | +| application/octet-stream | 22 | +| text/plain | 7 | +| application/xhtml+xml | 5 | +| application/rss+xml | 3 | +| binary/octet-stream | 3 | +| application/vnd.apple.installer+xml | 1 | +| application/x-bzip2 | 1 | +| application/x-rss+xml | 1 | +| plain/text | 1 | ("text/html" also includes error messages caused by input variables in URL.) + +## Sparkle feeds + +Sparkle feed that has item versions but not enclosure versions: + +```xml + + + + Caffeine + Most recent changes with links to updates. + en + + Version 1.4.3 + 21 + 1.4.3 + Sun, 14 April 2024 8:00:00 +0000 + + 11.0 +
  • Added Sparkle updater
  • ]]>
    +
    +
    +
    +``` + +Sparkle feed that has enclosure versions but not item versions: + +```xml + + + + coconutBattery changelog + https://www.coconut-flavour.com/updates/coconutBattery.xml + coconutBattery changelog + en + + Version 4.0.1 +
    All coconutBattery 3 Plus licenses were upgraded to coconutBattery 4 Plus Lifetime licenses.
    - coconutBattery 4 Plus -

    coconutBattery 4.0.1 | Dec 20, 2024

    • Fixed a bug that could cause displaying "NaN" in the history viewer for history that was imported from version 3
    • Info text if battery is not supported by lifetime viewer
    • If multiple adapters are connected, the one with the highest wattage is displayed
    • Print template selection now recognize Plus license correctly
    • Fixed display issues on iMac M3
    • The History Viewer "Save now" option shows matching icons for the device that will be saved
    • Fixed a bug where some coconutBattery 3 Plus licenses were not recognized correctly in coconutBattery 4
    • Added an option in the app settings to manually enable the coconutBattery menu bar
    • History Viewer now automatically selects first device when opened
    • History elements can be deleted using the context menu in the History Viewer
    • Toolbar state is now saved
    • Fixed battery manufacturer reading on some Macs
    • Battery health >100% is now displayed as 100% in non raw data mode
    • Fixed a bug that could cause the app displaying incorrectlry the charging state on Intel Macs

    coconutBattery 4.0.0 | Nov 30, 2024

    • Refined UI for improved usability
    • New App Icon
    • Realtime battery usage metrics for Macs
    • Improved device details viewer
    • Battery lifetime viewer now available for Macs
    • Re-engineered menu bar interface
    • Implemented low battery notifications for iPhones and iPads
    ]]>
    + + 12.4 +
    + + Version 3.9.18 + + 10.11.0 + +
    +
    +``` diff --git a/README.md b/README.md index de4f84e..d393e4a 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ Recipe Robot is the easiest way to create new [AutoPkg](https://github.com/autop [Download the latest release](https://github.com/homebysix/recipe-robot/releases/latest), or see detailed [requirements and installation steps](https://github.com/homebysix/recipe-robot/wiki/Installation-and-Requirements) on the wiki. +> [!TIP] +> As of 2025, over 20% of the publicly available recipes in the [AutoPkg organization](https://github.com/autopkg) were created with the help of Recipe Robot! + For helpful information on using Recipe Robot, including tutorials and troubleshooting information, see the [wiki](https://github.com/homebysix/recipe-robot/wiki). If you encounter a reproducible problem with Recipe Robot, I encourage you to open an [issue](https://github.com/homebysix/recipe-robot/issues) on GitHub. diff --git a/RELEASING.md b/RELEASING.md index aaddd0e..a4d9ade 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -39,12 +39,7 @@ 11. Create new release on GitHub with title format `Recipe Robot X.X.X`. Set label format to `vX.X.X`. Add notes from change log. Attach built disk image. -12. Trigger a GitHub Pages build, which updates the Sparkle feed ([using @huangyq23's method detailed here](https://www.yiqiu.me/2015/11/19/sparkle-update-on-github/)): - - git checkout gh-pages - git commit --allow-empty -m "Trigger gh-pages build" - git push - git checkout main +12. Manually update `appcast.xml` on the `gh-pages` branch. 13. Announce to [autopkg](https://macadmins.slack.com/archives/C056155B4) and other relevant channels, if desired. diff --git a/app/Cartfile.resolved b/app/Cartfile.resolved index 7c122a8..b424bde 100644 --- a/app/Cartfile.resolved +++ b/app/Cartfile.resolved @@ -1 +1 @@ -binary "https://sparkle-project.org/Carthage/Sparkle.json" "2.5.1" +binary "https://sparkle-project.org/Carthage/Sparkle.json" "2.6.4" diff --git a/app/Recipe Robot.xcodeproj/project.pbxproj b/app/Recipe Robot.xcodeproj/project.pbxproj index 7ee830d..64709f8 100644 --- a/app/Recipe Robot.xcodeproj/project.pbxproj +++ b/app/Recipe Robot.xcodeproj/project.pbxproj @@ -530,7 +530,7 @@ CODE_SIGN_ENTITLEMENTS = "Recipe Robot/Recipe Robot.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1038; + CURRENT_PROJECT_VERSION = 1381; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 32SVX952DB; ENABLE_HARDENED_RUNTIME = YES; @@ -543,7 +543,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; - MARKETING_VERSION = 2.3.1; + MARKETING_VERSION = 2.3.2; PRODUCT_BUNDLE_IDENTIFIER = "com.elliotjordan.recipe-robot"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; @@ -558,7 +558,7 @@ CODE_SIGN_ENTITLEMENTS = "Recipe Robot/Recipe Robot.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1038; + CURRENT_PROJECT_VERSION = 1381; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = 32SVX952DB; ENABLE_HARDENED_RUNTIME = YES; @@ -571,7 +571,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = "$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)"; - MARKETING_VERSION = 2.3.1; + MARKETING_VERSION = 2.3.2; PRODUCT_BUNDLE_IDENTIFIER = "com.elliotjordan.recipe-robot"; PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; diff --git a/app/Recipe Robot/Base.lproj/Main.storyboard b/app/Recipe Robot/Base.lproj/Main.storyboard index e91a9dd..02812b5 100644 --- a/app/Recipe Robot/Base.lproj/Main.storyboard +++ b/app/Recipe Robot/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + diff --git a/app/Recipe Robot/Info.plist b/app/Recipe Robot/Info.plist index 41d331b..3711409 100644 --- a/app/Recipe Robot/Info.plist +++ b/app/Recipe Robot/Info.plist @@ -21,7 +21,7 @@ CFBundleSignature RRBT CFBundleVersion - 1375 + 1396 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/scripts/recipe-robot b/scripts/recipe-robot index b879bbe..0cee865 100755 --- a/scripts/recipe-robot +++ b/scripts/recipe-robot @@ -44,7 +44,7 @@ if sys.version_info.major < 3: print("ERROR: This version of Recipe Robot requires AutoPkg 2 and Python 3.") sys.exit(1) -# TODO (Shea): Clean up importing from our library. +# TODO: Clean up importing from our library. import recipe_robot_lib from recipe_robot_lib import tools from recipe_robot_lib.exceptions import RoboError, RoboException @@ -88,7 +88,7 @@ def main(): first_timer = prefs.get("RecipeCreateCount", 0) == 0 # Collect facts from the input path, based on the type of path. - # TODO (Shea): Standardize on always returning Facts, even though they + # TODO: Standardize on always returning Facts, even though they # are passed by reference, to remove ambiguity about what is happening. process_input_path(facts) diff --git a/scripts/recipe_robot_lib/__init__.py b/scripts/recipe_robot_lib/__init__.py index 7b83f5d..41830c6 100644 --- a/scripts/recipe_robot_lib/__init__.py +++ b/scripts/recipe_robot_lib/__init__.py @@ -24,6 +24,6 @@ from __future__ import absolute_import -# TODO (Shea): We can import stuff better here to cut down on length of calls. +# TODO: We can import stuff better here to cut down on length of calls. from . import tools # noqa: F401 from .recipe_generator import generate_recipes # noqa: F401 diff --git a/scripts/recipe_robot_lib/curler.py b/scripts/recipe_robot_lib/curler.py index bf68e8a..bd976cb 100644 --- a/scripts/recipe_robot_lib/curler.py +++ b/scripts/recipe_robot_lib/curler.py @@ -118,7 +118,7 @@ def parse_curl_error(proc_stderr): try: curl_err = proc_stderr.rstrip("\n") curl_err = curl_err.split(None, 2)[2] - except IndexError: + except (AttributeError, IndexError): pass return curl_err diff --git a/scripts/recipe_robot_lib/inspect.py b/scripts/recipe_robot_lib/inspect.py index 33f5c39..5818829 100644 --- a/scripts/recipe_robot_lib/inspect.py +++ b/scripts/recipe_robot_lib/inspect.py @@ -861,7 +861,7 @@ def inspect_bitbucket_url(input_path, args, facts): "Getting information from latest BitBucket release...", LogLevel.VERBOSE ) if "values" in parsed_release: - # TODO (Elliot): Use find_supported_release() instead of these + # TODO: Use find_supported_release() instead of these # nested loops. May need to flatten the 'asset' dict first. for this_format in ALL_SUPPORTED_FORMATS: for asset in parsed_release["values"]: @@ -990,7 +990,7 @@ def inspect_disk_image(input_path, args, facts): for this_file in os.listdir(dmg_mount): if this_file.lower().endswith(".app"): # Copy app to cache folder. - # TODO(Elliot): What if .app isn't on root of dmg mount? (#26) + # TODO: What if .app isn't on root of dmg mount? (#26) attached_app_path = os.path.join(dmg_mount, this_file) cached_app_path = os.path.join(CACHE_DIR, "unpacked", this_file) robo_print("Copying %s into cache..." % this_file, LogLevel.VERBOSE, 4) @@ -1135,7 +1135,7 @@ def inspect_download_url(input_path, args, facts): headers = {} # Download the file for continued inspection. - # TODO(Elliot): Maybe something like this is better for downloading + # TODO: Maybe something like this is better for downloading # big files? https://gist.github.com/gourneau/1430932 (#24) robo_print("Downloading file for further inspection...", LogLevel.VERBOSE) @@ -1718,7 +1718,7 @@ def inspect_pkg(input_path, args, facts): facts["warnings"].append( "Yo dawg, I found a flat package inside this flat package!" ) - # TODO (Elliot): Recursion! Any chance for a loop here? + # TODO: Recursion! Any chance for a loop here? facts = inspect_pkg(os.path.join(dirpath, filename), args, facts) elif filename == "PackageInfo": robo_print( @@ -1876,6 +1876,7 @@ def inspect_sourceforge_url(input_path, args, facts): # Example: http://grandperspectiv.sourceforge.net/screenshots.html marker = ".sourceforge.net" proj_str = ( + # Requires Python 3.9+ input_path.removeprefix("https://www.") .removeprefix("http://www.") .removeprefix("https://") @@ -1956,7 +1957,7 @@ def inspect_sourceforge_url(input_path, args, facts): LogLevel.VERBOSE, ) for item in doc.iterfind("channel/item"): - # TODO(Elliot): The extra-info tag is not a reliable + # TODO: The extra-info tag is not a reliable # indicator of which item should actually be downloaded. # (#21) Example: # https://sourceforge.net/projects/grandperspectiv/rss @@ -2158,18 +2159,27 @@ def inspect_sparkle_feed_url(input_path, args, facts): sparkle_ns = "{http://www.andymatuschak.org/xml-namespaces/sparkle}" sparkle_provides_version = False sparkle_info = [] - for item in doc.iterfind("channel/item/enclosure"): - encl_vers = item.get(sparkle_ns + "version") - encl_shortvers = item.get(sparkle_ns + "shortVersionString") - if encl_vers or encl_shortvers: - sparkle_provides_version = True - sparkle_info.append( - { - "url": item.attrib.get("url", ""), - "version": encl_vers, - "shortVersionString": encl_shortvers, - } - ) + for item in doc.iterfind("channel/item"): + try: + item_vers = item.find(sparkle_ns + "version").text + except AttributeError: + item_vers = None + try: + item_shortvers = item.find(sparkle_ns + "shortVersionString").text + except AttributeError: + item_shortvers = None + for encl in item.iterfind("enclosure"): + encl_vers = encl.get(sparkle_ns + "version") + encl_shortvers = encl.get(sparkle_ns + "shortVersionString") + if any([item_vers, item_shortvers, encl_vers, encl_shortvers]): + sparkle_provides_version = True + sparkle_info.append( + { + "url": encl.attrib.get("url", ""), + "version": encl_vers or item_vers, + "shortVersionString": encl_shortvers or item_shortvers, + } + ) # Remove items with unusable URLs. sparkle_nones = (None, "", "null", "n/a", "none") diff --git a/scripts/recipe_robot_lib/recipe_generator.py b/scripts/recipe_robot_lib/recipe_generator.py index 211757c..6e8a881 100644 --- a/scripts/recipe_robot_lib/recipe_generator.py +++ b/scripts/recipe_robot_lib/recipe_generator.py @@ -86,7 +86,7 @@ def generate_recipes(facts, prefs): raise_if_recipes_cannot_be_generated(facts, preferred) # We have enough information to create a recipe set, but with assumptions. - # TODO(Elliot): This code may not be necessary if inspections do their job. + # TODO: This code may not be necessary if inspections do their job. if "codesign_reqs" not in facts and "codesign_authorities" not in facts: facts["reminders"].append( "I can't tell whether this app is codesigned or not, so I'm " @@ -104,7 +104,7 @@ def generate_recipes(facts, prefs): ) facts["version_key"] = "CFBundleShortVersionString" - # TODO(Elliot): Run `autopkg repo-list` once and store the resulting value + # TODO: Run `autopkg repo-list` once and store the resulting value # for future use when detecting missing required repos, rather than running # `autopkg repo-list` separately during each check. (For example, the # FileWaveImporter repo must be present to run created filewave recipes.) @@ -118,7 +118,7 @@ def generate_recipes(facts, prefs): build_recipes(facts, preferred, prefs) - # TODO (Shea): As far as I can tell, the only pref that changes is the + # TODO: As far as I can tell, the only pref that changes is the # recipe created count. Move out from here! # Save preferences to disk for next time. save_user_defaults(prefs) @@ -279,7 +279,7 @@ def get_generation_func(facts, prefs, recipe): if recipe["type"] in ("munki", "pkg") and facts.is_from_app_store(): func_name.insert(1, "app_store") - # TODO (Shea): This is a hack until I can use AbstractFactory for this. + # TODO: This is a hack until I can use AbstractFactory for this. generation_func = globals()["_".join(func_name)] return generation_func @@ -300,7 +300,7 @@ def generate_download_recipe(facts, prefs, recipe): Returns: Recipe: Newly updated Recipe object suitable for converting to plist. """ - # TODO(Elliot): Handle signed or unsigned pkgs wrapped in dmgs or zips. + # TODO: Handle signed or unsigned pkgs wrapped in dmgs or zips. bundle_type, bundle_name_key = get_bundle_name_info(facts) if facts.is_from_app_store(): @@ -313,7 +313,7 @@ def generate_download_recipe(facts, prefs, recipe): "Downloads the latest version of %s." % facts[bundle_name_key] ) - # TODO (Shea): Extract method(s) to get_source_processor() + # TODO: Extract method(s) to get_source_processor() if "barebones_product" in facts: BarebonesURLProvider = processor.ProcessorFactory( "com.github.autopkg.download.bbedit/BarebonesURLProvider", @@ -348,7 +348,7 @@ def generate_download_recipe(facts, prefs, recipe): recipe.append_processor(sparkle_processor) - # TODO (Shea): Extract method(s) to get_source_processor() + # TODO: Extract method(s) to get_source_processor() elif "github_repo" in facts: if facts.get("use_asset_regex", False): gh_release_info_provider = processor.GitHubReleasesInfoProvider( @@ -361,7 +361,7 @@ def generate_download_recipe(facts, prefs, recipe): ) recipe.append_processor(gh_release_info_provider) - # TODO (Shea): Extract method(s) to get_source_processor() + # TODO: Extract method(s) to get_source_processor() elif "sourceforge_id" in facts: SourceForgeURLProvider = processor.ProcessorFactory( "com.github.jessepeterson.munki.GrandPerspective/SourceForgeURLProvider", @@ -431,7 +431,7 @@ def generate_download_recipe(facts, prefs, recipe): end_of_check_phase = processor.EndOfCheckPhase() recipe.append_processor(end_of_check_phase) - # TODO (Shea): Refactor to get_codesigning and get_unarchiver funcs. + # TODO: Refactor to get_codesigning and get_unarchiver funcs. if facts.get("codesign_reqs") or facts.get("codesign_authorities"): if facts["download_format"] in SUPPORTED_ARCHIVE_FORMATS: unarchiver = processor.Unarchiver() @@ -451,7 +451,7 @@ def generate_download_recipe(facts, prefs, recipe): ) elif facts["download_format"] in SUPPORTED_INSTALL_FORMATS: # The download is in pkg format, and the pkg is signed. - # TODO(Elliot): Need a few test cases to prove this works. + # TODO: Need a few test cases to prove this works. input_path = "%pathname%" else: facts["warnings"].append( @@ -464,7 +464,7 @@ def generate_download_recipe(facts, prefs, recipe): codesigverifier = get_code_signature_verifier(input_path, facts) recipe.append_processor(codesigverifier) - # TODO (Shea): Extract method -> get_versioner + # TODO: Extract method -> get_versioner if needs_versioner(facts): versioner = processor.Versioner() if ( @@ -929,7 +929,7 @@ def generate_pkg_recipe(facts, prefs, recipe): """ bundle_type, bundle_name_key = get_bundle_name_info(facts) # Can't make this recipe without a bundle identifier. - # TODO(Elliot): Bundle id is also provided by AppDmgVersioner and some + # TODO: Bundle id is also provided by AppDmgVersioner and some # Sparkle feeds. When those are present, can we proceed even though we # don't have bundle_id in facts? (#40) if "bundle_id" not in facts: @@ -1547,7 +1547,7 @@ def generate_filewave_recipe(facts, prefs, recipe): } ) elif facts.get("download_format") in SUPPORTED_INSTALL_FORMATS: - # TODO(Elliot): Fix this. (#41) + # TODO: Fix this. (#41) facts["warnings"].append( "Sorry, I don't yet know how to create filewave recipes from pkg " "downloads." diff --git a/scripts/recipe_robot_lib/tools.py b/scripts/recipe_robot_lib/tools.py index 7973477..9b0532f 100644 --- a/scripts/recipe_robot_lib/tools.py +++ b/scripts/recipe_robot_lib/tools.py @@ -52,7 +52,7 @@ # pylint: enable=no-name-in-module -__version__ = "2.3.1" +__version__ = "2.3.2" ENDC = "\033[0m" BUNDLE_ID = "com.elliotjordan.recipe-robot" PREFS_FILE = os.path.expanduser("~/Library/Preferences/%s.plist" % BUNDLE_ID) @@ -316,7 +316,7 @@ def recipe_dirpath(app_name, dev, prefs): app_name = app_name.replace(char[0], char[1]) path_components = [prefs["RecipeCreateLocation"]] if dev is not None: - # TODO (Elliot): Put this in the preferences. + # TODO: Put this in the preferences. if prefs.get("StripDeveloperSuffixes", False) is True: dev = strip_dev_suffix(dev) for char in char_replacements: @@ -597,7 +597,7 @@ def create_existing_recipe_list(facts): RoboError: Standard exception raised when Recipe Robot cannot proceed. """ app_name = facts["app_name"] - # TODO(Elliot): Suggest users create GitHub API token to prevent + # TODO: Suggest users create GitHub API token to prevent # limiting. (#29) # Update search index JSON cache diff --git a/scripts/test/sample_data.yaml b/scripts/test/sample_data.yaml index 59c3786..5a73d12 100644 --- a/scripts/test/sample_data.yaml +++ b/scripts/test/sample_data.yaml @@ -185,11 +185,6 @@ developer: Roman Sokolov input_path: https://raw.github.com/beardedspice/beardedspice/distr/publish/beardedspice-appcast.xml -- app_name: BlueJeans - bundle_id: com.bluejeansnet.Blue - developer: Blue Jeans Network - input_path: https://swdl.bluejeans.com/desktop-app/mac/ga.appcast.xml - - app_name: BonjourBrowser bundle_id: com.tildesoft.RendezvousBrowser developer: Tildesoft @@ -200,10 +195,10 @@ developer: Sonny Software input_path: https://www.sonnysoftware.com/Bookends.dmg -- app_name: Boom 2 - bundle_id: com.globaldelight.Boom2 +- app_name: Boom 3D + bundle_id: com.globaldelight.Boom3D developer: Global Delight Technologies - input_path: https://www.globaldelight.com/boom/download/2x/web/boom2.dmg + input_path: https://dfvk972795zr9.cloudfront.net/Boom3Dmac/webstore/Boom3D.dmg - app_name: Brave bundle_id: com.electron.brave @@ -255,11 +250,6 @@ developer: Cisco input_path: https://proximity.cisco.com/mac/Proximity.dmg -- app_name: Cisco Spark - bundle_id: Cisco-Systems.Spark - developer: Cisco - input_path: https://download.ciscospark.com/mac/CiscoSpark.dmg - - app_name: Clarify bundle_id: com.bluemangolearningsystems.clarify-osx developer: Blue Mango Learning Systems @@ -320,11 +310,6 @@ developer: Realmac Software input_path: https://dl.devmate.com/com.realmacsoftware.deepdreamer/DeepDreamer.zip -- app_name: Delicious Library 3 - bundle_id: com.delicious-monster.library3 - developer: Delicious Monster - input_path: http://delicious-monster.com/downloads/DeliciousLibrary3.zip - - app_name: Desktop Curtain bundle_id: com.manytricks.DesktopCurtain developer: Many Tricks @@ -393,7 +378,7 @@ - app_name: DraftSight bundle_id: com.3ds.draftsight developer: 3ds - input_path: https://dl-ak.solidworks.com/nonsecure/draftsight/2023SP4-1-5WQLABEM/DraftSight.pkg + input_path: https://dl-ak.solidworks.com/nonsecure/draftsight/2025SP0-1-SQLJASWL/DraftSight.pkg - app_name: duet bundle_id: com.kairos.duet @@ -496,9 +481,9 @@ input_path: https://overcast.fm/appcast/Forecast.xml - app_name: ForkLift - bundle_id: com.binarynights.ForkLift2 + bundle_id: com.binarynights.ForkLift developer: BinaryNights - input_path: https://updates.binarynights.com/ForkLift3/update.xml + input_path: https://updates.binarynights.com/ForkLift/update.xml - app_name: FramerX bundle_id: com.framer.x @@ -510,11 +495,6 @@ developer: FuzeBox Software Corporation input_path: https://citadel.thinkingphones.com/api/v1/applications/fuzeapp/mac/versions/latest/download/installer -- app_name: Gas Mask - bundle_id: ee.clockwise.gmask - developer: Siim Raud - input_path: http://gmask.clockwise.ee/check_update/ - - app_name: Geekbench 4 bundle_id: com.primatelabs.Geekbench4 developer: Primate Labs @@ -605,11 +585,6 @@ developer: Ioannis Zafeiropoulos input_path: https://s3.amazonaws.com/iswift/iswift.xml -- app_name: iTaskX3 - bundle_id: at.techno-grafik.iTaskX3 - developer: Techno-Grafik - input_path: https://www.itaskx3.com/services/appcast.ashx - - app_name: iZip bundle_id: com.iboostup.izip developer: iBoostUp @@ -650,11 +625,6 @@ developer: Docker input_path: https://github.com/docker/kitematic -- app_name: KiteStudentPortal - bundle_id: org.ats.kitestudentportal - developer: Achievement and Assessment Institute - input_path: https://files.kiteaai.org/installers/studentportal/latest/mac/Kite%20Student%20Portal.dmg - - app_name: KNIME_Analytics_Platform bundle_id: org.knime.product developer: KNIME @@ -838,7 +808,7 @@ - app_name: ParseHub bundle_id: org.mozilla.parsehub developer: ParseHub - input_path: https://www.parsehub.com/static/client/parsehub.dmg + input_path: https://www.parsehub.com/static/client/ParseHub.dmg - app_name: Pathological bundle_id: com.celestialteapot.Pathological @@ -855,11 +825,6 @@ developer: Xuepeng Zhang input_path: https://www.ireador.com/downloads/PDFKit.dmg -- app_name: Persona - bundle_id: com.marinersoftware.persona - developer: Mariner Software - input_path: https://www.marinersoftware.com/sparkle/persona/persona.xml - - app_name: PIA bundle_id: fr.cnil.linc.pia developer: CNIL @@ -890,11 +855,6 @@ developer: Alex Marchant input_path: https://www.plugformac.com/updates/plug2/sparklecast.xml -- app_name: Pock - bundle_id: com.pigigaldi.pock - developer: Pierluigi Galdi - input_path: https://pock.app/download?file=pock_0_9_0__22.zip&nw=1 - - app_name: PollEv Presenter bundle_id: com.polleverywhere.PollEv-Presenter developer: Poll Everywhere @@ -963,7 +923,7 @@ - app_name: Resilio Sync bundle_id: com.resilio.Sync developer: Resilio - input_path: https://download-cdn.getsync.com/stable/osx/Resilio-Sync.dmg + input_path: https://download-cdn.resilio.com/stable/mac/osx/0/Resilio-Sync.dmg - app_name: Resolutionator bundle_id: com.manytricks.Resolutionator @@ -1033,7 +993,7 @@ - app_name: SecuritySpy bundle_id: com.bensoftware.SecuritySpy developer: Ben Software - input_path: https://www.bensoftware.com/securityspy/SecuritySpy.dmg + input_path: https://www.bensoftware.com/securityspy/releases/SecuritySpy.dmg - app_name: SelfControl bundle_id: org.eyebeam.SelfControl @@ -1090,11 +1050,6 @@ developer: Facebook input_path: https://www.facebook.com/sparkarmacos/download/ -- app_name: Sparkle - bundle_id: eu.riverdesign.sparkle - developer: River - input_path: https://sparkleapp.com/update/Sparkle.zip - - app_name: StretchLink bundle_id: com.brettterpstra.stretchlink developer: Brett Terpstra @@ -1218,7 +1173,7 @@ - app_name: uBar bundle_id: ca.brawer.uBar developer: Brawer Canada - input_path: https://brawersoftware.com/appcasts/feeds/ubar/ubar4.xml + input_path: https://brawersoftware.com/downloads/ubar/ubar422.zip - app_name: Unlox bundle_id: com.kanecheshire.macID-macOS @@ -1230,11 +1185,6 @@ developer: Many Tricks input_path: https://manytricks.com/usher/appcast.xml -- app_name: uTorrent - bundle_id: com.bittorrent.uTorrent - developer: BitTorrent - input_path: http://download.ap.bittorrent.com/track/stable/endpoint/utmac/os/osx - - app_name: Vanilla bundle_id: net.matthewpalmer.Vanilla developer: Matthew Palmer @@ -1245,11 +1195,6 @@ developer: Vectorworks input_path: http://release.vectorworks.net/nnapub/mac/2018/SP0/389445/NNA/eng/installer5/Vectorworks-2018-Viewer.dmg -- app_name: Vienna - bundle_id: uk.co.opencommunity.vienna2 - developer: Barijaona Ramaholimihaso - input_path: https://github.com/ViennaRSS/vienna-rss - - app_name: VimR bundle_id: com.qvacua.VimR developer: Tae Won Ha @@ -1258,7 +1203,7 @@ - app_name: VirtualC64 bundle_id: de.dirkwhoffmann.VirtualC64 developer: Prof. Dr. Dirk W. Hoffmann - input_path: https://github.com/dirkwhoffmann/virtualc64/releases/download/v4.6/VirtualC64.app.zip/VirtualC64Appcast.xml + input_path: https://github.com/dirkwhoffmann/virtualc64/releases/download/v5.1/VirtualC64.app.zip - app_name: Viscosity bundle_id: com.viscosityvpn.Viscosity @@ -1290,11 +1235,6 @@ developer: ID-DESIGN input_path: https://whatsizemac.com/software/whatsize6/whatsize.dmg -- app_name: Whiskey - bundle_id: com.nothingmagical.whiskey - developer: Sam Soffes - input_path: https://soffes.s3.us-east-1.amazonaws.com/Whiskey-357.zip - - app_name: WiFi Explorer bundle_id: com.adriangranados.wifiexplorer developer: Adrian Granados-Murillo diff --git a/scripts/test/test_functional.py b/scripts/test/test_functional.py index 00b2aed..7c8484f 100644 --- a/scripts/test/test_functional.py +++ b/scripts/test/test_functional.py @@ -41,8 +41,8 @@ # pylint: enable=unused-wildcard-import, wildcard-import -# TODO (Shea): Mock up an "app" for testing purposes. -# TODO (Shea): Add arguments to only produce certain RecipeTypes. This will +# TODO: Mock up an "app" for testing purposes. +# TODO: Add arguments to only produce certain RecipeTypes. This will # allow us to narrow the tests down. RECIPE_TYPES = ("download", "pkg", "munki", "install") @@ -99,8 +99,9 @@ def verify_processor_args(processor_name, recipe, expected_args): def get_output_path(prefs, app_name, developer, recipe_type=None): """Build a path to the output dir or output recipe for app_name.""" path = os.path.join(prefs.get("RecipeCreateLocation"), developer) + extension = ".yaml" if prefs.get("RecipeFormat") == "yaml" else "" if recipe_type: - path = os.path.join(path, "{}.{}.recipe".format(app_name, recipe_type)) + path = os.path.join(path, f"{app_name}.{recipe_type}.recipe{extension}") if not os.path.exists(path): print("[ERROR] {} does not exist.".format(path)) return os.path.expanduser(path)