Skip to content

This is a Google Apps Script library helps maintain the relevance of a script on the user's end.

License

Notifications You must be signed in to change notification settings

githnow/Google-Apps-Script-ScriptSync

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

48 Commits
 
 
 
 
 
 
 
 

Repository files navigation

ScriptSync

MIT License

Overview

This library helps maintain the relevance of a script on the user's end.

Description

ScriptSync is a library designed to make it easier for developers to quickly deploy scripts on the user side. It allows to update script files without requiring any direct involvement from the user.

Library's project key

1nUiajCHQReVwWPq7rNAvsIcWvPptmMUSzeytnzVHDpdoxUIvuX0e_reL

How to install

In order to use this library, please install this library.

  1. Install library.
    • Library's project key is 1nUiajCHQReVwWPq7rNAvsIcWvPptmMUSzeytnzVHDpdoxUIvuX0e_reL.
  2. Copy the dependencies of the Apps Script (appsscript.json).

About scopes

About the install of scopes using the library, this library requires installing scopes into the project that installed the library:

  • https://www.googleapis.com/auth/script.external_request
  • https://www.googleapis.com/auth/drive.scripts
  • https://www.googleapis.com/auth/drive.file
  • https://www.googleapis.com/auth/drive

IMPORTANT: Above 4 scopes are installed in this library. If you want to use Spreadsheets, please install the scopes for it using Manifests to the project installed this library.

Also

The library and your script template must be shared.

Methods

Libarary

Method Description
IO_GetSamples * Saves file with code examples in the user script.
getScriptContent Retrieves the content of the script file.
getScriptFiles Retrieves a list of files associated with a script based on its script_id.
getTemplateScriptFiles Fetches a list of template files (script_id of the template is defined in the script properties, default template id is set to the library's id).
assignTemplate Initializes the class and sets the ID of the template script as the data source.
createCalleeMap Generates a map representing function calls within a script, with an option to visualize it.

* - makes changes to the script file

Library Class

Method Description
assignTemplate Initializes the class and sets the ID of the template script as the data source.
General
commit * Applies the pending changes made to the script.
drop Discards the local changes made to the script, without reverting a commit.
viewChanges Displays a list of changes that will be applied to the script upon committing.
getChanges Retrieves a list of changes that will be applied to the script upon committing.
getTemplateId Retrieves the current ID of the script's template.
Operations
AddNewFile Adds a new file from the script template to the user script, replacing any existing file with the same name.
renameFile Renames a file within the script.
deleteFile Deletes a file from the script file object.
compareFilesByContent Compares the content of two files and returns true if they are identical, false otherwise.
createBlankFile Creates a new blank file within the script.
setCustomSource Sets the content of the source in a file within the script.
Appsscript
getLibraryInfo Retrieves information about a library from the user script or template.
updateLibraryInfo Updates library information in the user script file.
Additional
addFileToUserJson Adds a file to the user's script.
getFileFromTemplate Retrieves a file from the template script file object.

* - makes changes to the script file

Usage

User appsscript.json:

appsscript file, json:

{
  "timeZone": "Europe/Moscow",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "dependencies": {
    "enabledAdvancedServices": [
      {
        "userSymbol": "Drive",
        "serviceId": "drive",
        "version": "v3"
      }
    ],
    "libraries": [
      {
        "userSymbol": "ScriptSync",
        "libraryId": "1nUiajCHQReVwWPq7rNAvsIcWvPptmMUSzeytnzVHDpdoxUIvuX0e_reL",
        "version": "6"
      }
    ]
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/drive.scripts",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/drive"
  ]
}

User deploy.gs:

A sample script is as follows. This sample script copies code samples from the library to the current project.

function samples() {
  ScriptSync.IO_GetSamples();
}
  • The template_script_id identifier is stored in the library properties as a SETTINGS property, thats: {"template_script_id":"1nUiajCHQReVwWPq7rNAvsIcWvPptmMUSzeytnzVHDpdoxUIvuX0e_reL"}

You can set your script_id as follows: ScriptSync.assignTemplate(TemplateScriptId)

You can copy the library and set the property manually or using the method (inside your library):

setSetting_('template_script_id', 'my_template_id')

Like this:

function setMyTemplateId() {
  setSetting_('template_script_id', 'my_template_id');
}

Sample scripts

Sample 1: Copying new files

function copyFiles() {
  // script_id of the template script
  const template_script_id = "your_template_script_id";

  // get an array of files to copy from the template
  const filesToCopy = ScriptSync.getScriptFiles(template_script_id);

  /* Initialize the template script updater */
  const updater = ScriptSync.assignTemplate(template_script_id);

  filesToCopy.forEach(function(item) {
    if (item.file !== 'appsscript') {
      // add the file to the updater
      updater.AddNewFile(item.file);
    }
  });

  // AND set your own specific name and type
  const fileToCopy = 'appsscript';
  updater.AddNewFile(fileToCopy, `from_template_${fileToCopy}`, 'html');

  // shows the changes (source trimmed to 30 characters)
  updater.viewChanges(30);

  // apply the changes if there are no errors (using "false" flag)
  updater.commit(false);

  /*
    // OR try to apply the changes anyway
    try {
      updater.commit(updater.result);
    } catch (e) {
      console.log(e.message);
    }
  */
}

Sample 2: Add custom source

function addMySource() {
  /* Initialize your template script */
  const template_script_id = "your_template_script_id";
  const updater = ScriptSync.assignTemplate(template_script_id);

  // any working code
  const myFunctions = {
    def: function defined() {
      /* Comments are also included */
      console.log("Hello world!");
    }
  }

  // creating a new file & renaming & set custom code
  updater.createBlankFile("the_code", "html")
    .renameFile("the_code", "sample_code", "gs")
    .setCustomSource("sample_code", "gs", myFunctions.def);

  // creating a new file & set custom text & shows the changes
  updater.createBlankFile("changes", "html")
    .setCustomSource("changes", "html", "Today updates: ...")
    .viewChanges(30);

  // waiting for interruption by user
  Utilities.sleep(20000);

  // apply the changes with ignore errors (default)
  const result = updater.commit();
  console.log(result);
}

Sample 3: Updating if any changes

function addMySource() {
  /* Initialize your template script */
  const template_script_id = "your_template_script_id";
  const updater = ScriptSync.assignTemplate(template_script_id);

  const match = updater.compareFilesByContent("template_code", "script_code");

  if (!match) {
    updater.AddNewFile("template_code", "script_code")
      .createBlankFile("notice", "html")
      .setCustomSource("notice", "html", "Your script was updated at ..")
      .commit();
  }
}

Sample 4: Set a specific library version in the script

function updateLibraryVersion(libraryId='', libraryName='', version) {
  const script_id = ScriptApp.getScriptId();
  const current_script_json = ScriptSync.getScriptContent(script_id);
  var appsscript_json = current_script_json.files.find(file => {
      return file.name === "appsscript"
  });

  if(appsscript_json) {
    appsscript_json = JSON.parse(appsscript_json.source);
    var library = appsscript_json.dependencies?.libraries?.find(lib => {
        return (
            lib.libraryId === libraryId
            || lib.userSymbol === libraryName
        );
    });

    if(library) {
      let new_version = version || Number(library.version) + 1;
      library.version = (new_version).toString();
      appsscript_json.source = JSON.stringify(appsscript_json, null, 2);
      const updater = ScriptSync.assignTemplate();
      updater.addFileToUserJson("appsscript", appsscript_json);
      updater.viewChanges(370);
      Utilities.sleep(20000);   // waiting for interruption by user (if needed)
      return updater.commit();  // after, apply the changes
    }
  }
  return false;
}

function do(e) {
  // ....
  const libraryId    = "library_script_id";
  const libraryName  = "LibraryNameUsersDefined";
  const updateResult = updateLibraryVersion(libraryId, libraryName);
  console.log(updateResult);
  //...
}

Sample 5: Set a specific library version in the script with updateLibraryInfo() method

function updateLibraryVersion() {
  // assign the template
  const updater = ScriptSync.assignTemplate();
  const library_id = "your_library_id";

  updater.updateLibraryInfo(
      {libraryId: library_id, version: "5"}
  ).commit();
}

Restrictions

PLEASE EXERCISE CAUTION WHEN RENAMING AND DELETING FILES!

DO NOT EXCEED THE LIMITATIONS SET BY APPS SCRIPT:

  • PROVIDE ONLY UNIQUE FILENAMES. FOR EXAMPLE, "file.html" AND "file.json" ARE NOT UNIQUE NAMES.
  • USE ONLY EXISTING FILE EXTENSIONS: html, gs, json. DO NOT INVENT NEW ONES.
  • DO NOT DELETE THE FILE: appsscript.json.

FAILURE TO COMPLY WITH THESE CONDITIONS MAY NOT ONLY RESULT IN ERROR CODES 400 OR 500

BUT ALSO RENDER THE SCRIPT FILE INACCESSIBLE. PLEASE BE ATTENTIVE.

Important

  • If you want to use it, please add a star.

Licence

MIT

Author

Githnow

If you have any questions and commissions for me, feel free to tell me.

Update History

TOP